Содержание статьи
Настольные компы постепенно выходят из моды, уступая место различным мобильным девайсам, таким как смартфоны, планшеты и ноутбуки. Внутренние накопители подобных устройств обычно невелики, поэтому рано или поздно встает вопрос об организации домашнего файлового хранилища, которое бы выступало в роли сетевой файлопомойки и торрент-клиента, доступных всем устройствам. К счастью, такое хранилище легко собрать из подручных материалов.
Введение
В этой статье я расскажу о том, как собрал собственный домашний NAS, потратив на это в общей сложности около 700 российских рублей. NAS получился стойким к сбоям (привет RAID 1), перебоям в питании (благодаря старенькому UPS’у), с экспортом файловой системы по NFS и SFTP, а также торрент-демоном, который включается по ночам и отрубается днем. Решение задачи заняло в сумме около часа, не считая ожидания китайских железок с dealextreme.com.
Часть 1. Компоненты
Основной компонент, используемый для решения задачи, был найден в шкафу. Это древний системный блок на базе Pentium II (первый и последний процессор, втыкаемый в слот!) с 64 Мб оперативной памяти и дохлым жестким диском на 10 Гб. Громоздкий корпус мне был не нужен, поэтому материнская плата с процессором, металлической платой, при помощи которой она крепилась к корпусу, оперативной памятью и видеокартой была вынута вместе с блоком питания. Также от корпуса был отсоединен крепеж для жестких дисков, после чего пластмассовая коробка, гордо именуемая «Корпус AT», отправилась в утиль. Далее началась работа по сборке всех необходимых компонентов без самого корпуса. Путем недолгих раздумий было решено прикрутить все необходимое к тому самому металлическому каркасу для крепления материнской платы. Сама материнка оказалась формата mini-AT, поэтому места на плате оставалось достаточно для монтирования блока питания и крепежа для жестких дисков. Оставалось только просверлить дополнительные отверстия.
Дабы избежать лишнего шума, корпус блока питания (а также процессора) был снят и утилизирован вместе с уже мертвыми вентиляторами. Далее блок питания и крепеж для жестких дисков были прикручены к металлическому каркасу прямо рядом с материнской платой. Сразу был установлен SATA-диск на 500 Гб, уже год пылившийся в том же шкафу. Далее началось решение проблемы IDE vs SATA, которое затянулось на три недели. Дело в том, что необходимо было, во-первых, SATA-диск подключить к IDE-материнке, а во-вторых, как-то решить проблему загрузки ОС, которая должна была быть установлена именно на IDE-диск. Я принял решение установить ОС на двухгигабайтную карту памяти Compact Flash, а для ее подключения использовать специальный переходник CF to IDE, заказанный на dealextreme.com за пять долларов. Там же сразу был заказан SATA-контроллер на чипе VIA VT6421A производства знаменитого китайского бренда Noname, стоимостью десять долларов, а также пара кабелей питания IDE — SATA по доллару за каждый.
Через три недели все это хозяйство вместе с игрушечной машинкой, работающей от солнечной энергии, зачем-то заказанной мной за два доллара, было получено на почте и подключено к остальному хозяйству. В результате была собрана система, показанная на фотографии. Из механических элементов на ней остался только жесткий диск, издающий не так уж и много шума. Дополнительно к материнке был подключен сверхбюджетный Ethernet-адаптер Realtek, доставшийся мне от провайдера и долгое время лежавший в шкафу. Видеокарту тоже пришлось оставить на месте, так как производители старых бюджетных материнок не представляли себе компьютера без монитора и встраивали в материнку механизм «защиты», запрещающий загрузку ОС без видеокарты.
Часть 2. Установка ОС
Далее следовало выбрать ОС, подходящую для установки на «франкенштейна». Я не фанатик, поэтому сделал сухой логический вывод о том, что держать на устройстве FreeBSD будет удобнее с точки зрения как управления, так и полученной в результате функциональности. FreeBSD подходила для решения задачи практически идеально, не требуя доустановки дополнительного ПО.
ОС была получена с официального сайта freebsd.org — я выбрал девятую версию, хотя сомневающиеся могут остановиться на версии 8.3, как более протестированной и объезженной. Далее образ был нарезан на болванку, к компу был подключен айдишный CD-привод, который я чуть не выбросил вместе с корпусом, а также клавиатура и монитор. После недолгих копаний в настройках BIOS машина начала грузиться с диска, выдав на экран приглашение нового инсталлятора FreeBSD 9.
Инсталлятор FreeBSD 9
В качестве диска для установки я выбрал CF-карту, а если точнее — первый IDE-диск, и разбил его следующим образом:
- 128 Мб — swap
- 256 Мб — /
- 256 Мб — /var
- остальное — /usr
Место для домашних каталогов пользователей я отводить не стал, поскольку все файло так или иначе будет храниться на другом диске, подключенном к SATA-контроллеру. После окончания весьма непродолжительной для такого динозавра установки машина была перезагружена и встретила меня приглашением к входу в систему. Войдя под учетной записью root, я сразу создал дополнительного бесправного пользователя j1m и поместил его в группу wheel:
# adduser j1m
Он мне понадобится для входа по SSH, открывать который для root’а я не собирался. Далее следовало проверить сеть с помощью ifconfig и пинга. В моем случае все заработало само собой, так как сервер был подключен к Wi-Fi-роутеру, который назначил серверу IP-адрес 192.168.0.100 и отдал свой адрес в качестве DNS-сервера. Пинг показал, что внешний мир был доступен, включая интернет и другие подсоединенные к роутеру устройства. Если в твоем случае сеть придется настраивать вручную, то это просто сделать с помощью редактирования /etc/rc.conf:
ifconfig_rl0="inet 192.168.0.100 netmask 255.255.255.0"
defaultrouter="192.168.0.1"
Также необходимо добавить запись о DNS-сервере (здесь 8.8.8.8 не пример, а реальный DNS-сервер Гугла):
# echo 'nameserver 8.8.8.8' >> /etc/resolv.conf
С помощью dmesg также было выяснено, что SATA-диск успешно подхватился и получил имя ad4 (ad0 — ad3 зарезервированы за встроенным IDE-контроллером). Значит, самое время отключить клавиатуру и мышь, поставить сервер на его законное место, войти по SSH и приступить к созданию файловой системы и всех остальных дел.
Переходник CF2IDE китайского производства
Часть 3. RAID
На момент написания статьи мой сервер был оснащен одним диском и только готовился к приему двух емких носителей и созданию RAID-массива на их основе. Поэтому рассказ о RAID будет носить чисто теоретический характер, что не страшно, потому что RAID во FreeBSD — это просто, и такая процедура проделывалась множество раз на других машинах без сучка и задоринки.
Итак, представим, что к нашему SATA-контроллеру подключено уже два диска и мы хотим объединить их в RAID-массив. Для этого можно использовать либо железный RAID-контроллер (для управления которым придется устанавливать дополнительные утилиты, разбираться со спецификой производителя и надеяться, что он не глючит), либо простой, удобный и проверенный временем механизм управления RAID’ами во FreeBSD. Остановимся на втором варианте.
Начиная с пятой ветки, все операции с дисками во фряхе производятся с помощью подсистемы GEOM, которая пропускает через себя все запросы ввода-вывода и модифицирует их различным образом с помощью подключаемых классов модулей. Таких модулей существует несколько десятков, и служат они разным целям — от проброса дискового ввода-вывода по сети и шифрования до создания RAID-массивов самых разных уровней. Нас интересуют два модуля: gmirror, предназначенный для зеркалирования дисков, то есть создания RAID 1, и gstripe, который пишет данные попеременно на два диска, реализуя RAID 0. Разные ситуации могут потребовать разных типов RAID-массивов. Для хранения HD-фильмов лучше использовать RAID 0, чтобы получить больше пространства, а для хранения семейных видеоархивов, документов и редкой музыки в формате FLAC лучше использовать RAID 1, который позволит сохранить данные даже в случае смерти одного из дисков. Поэтому рассмотрим оба варианта.
Итак, зеркалирование. Чтобы создать массив RAID 1 из двух дисков, достаточно загрузить модуль gmirror и выполнить одну простую команду:
# gmirror load
# gmirror label -v -b split -s 2048 data ad4 ad6
Здесь «label» — это указ команде gmirror инициализировать массив, опции «-b split -s 2048» задают алгоритм балансировки «split», который будет читать данные с обоих дисков одновременно чанками размером 2048 байт. Это оптимальный, наиболее производительный вариант, однако по желанию ты можешь выбрать один из трех других алгоритмов: «load» — чтение с наименее загруженного диска, «prefer» — чтение с диска, имеющего больший приоритет (причем чем позже диск был добавлен в массив, тем выше его приоритет — логика здесь в том, чтобы создавать больше нагрузки на новые диски, подключенные позже взамен умерших), и «round-robin» — то есть по кругу, один запрос одному диску, другой — другому. Последние три опции — это имя массива (оно может быть произвольным) и список дисков, объединяемых в массив.
Если на одном из подключаемых дисков уже есть данные и ты не хочешь их терять, то вместо предыдущей команды лучше использовать следующие две:
# gmirror label -v -b split -s 2048 data ad4
# gmirror insert data ad6
Первая команда создаст массив из одного диска, а вторая подключит к нему второй диск, после чего начнется процесс синхронизации, за ходом которого можно следить с помощью команды «gmirror status». Теперь RAID 0. Объединить диски в такой массив также очень просто:
# gstripe load
# gstripe label -v -s 131072 data ad4 ad6
Опция «-s 131072» здесь указывает размер страйпа (128 Кб), то есть чанка данных, который будет попеременно записываться то на один, то на другой диск. В результате информация окажется равномерно размыта по обоим дискам, и гибель одного из них приведет к потере всех данных. Также не стоит даже думать о сохранении существующих данных перед созданием массива.
Китайский SATA RAID-контроллер
После того как массив будет создан, на нем следует создать файловую систему, смонтировать ее к нужному каталогу, добавить запись в fstab и заставить систему подцеплять зеркало/страйп при загрузке. Для RAID 1 это можно сделать так:
# newfs /dev/mirror/data
# mount /dev/mirror/data /mnt
# echo '/dev/mirror/data /mnt ufs rw 2 2' >> /etc/fstab
# echo 'geom_mirror_load="YES"' >> /boot/loader.conf
Для RAID 0 — так:
# newfs /dev/stripe/data
# mount /dev/stripe/data /mnt
# echo '/dev/stripe/data /mnt ufs rw 2 2' >> /etc/fstab
# echo 'geom_stripe_load="YES"' >> /boot/loader.conf
Hard-disk failure
Если один из дисков в конфигурации RAID 1 вышел из строя, следует выполнить команду:
# gmirror forget data
Заменить диск и вновь добавить его в массив:
# gmirror insert data ad6
Часть 4. Torrent и NFS
Мы помним, что создавали файлохранилище для расшаривания данных между несколькими устройствами, поэтому надо найти способ экспорта файлов во внешний мир. Фактически такая функциональность уже есть, и она работает: это SFTP-сервер, интегрированный в SSH-сервер. В любой момент мы можем получить доступ к данным с любого устройства, зная имя и пароль.
SFTP-клиент встроен во многие менеджеры файлов для Android
С другой стороны, SFTP неудобен тем, что не позволяет монтировать ресурс и работать с файлами как с локальными (да, есть реализации виртуальных ФС на Fuse, но попробуй воспользоваться ими в Windows или Android). Поэтому нам нужна сетевая файловая система, а именно — NFS (ничего не имею против CIFS/Samba, но я не любитель сложных систем).
NFS во FreeBSD настроить очень просто. Фактически, все, что нужно сделать, — это добавить три строки в /etc/rc.conf:
rpcbind_enable="YES"
nfs_server_enable="YES"
mountd_flags="-r"
Первая строка активирует сервис rpcbind, необходимый для работы NFS, вторая — сам сервер, а третья — демон монтирования. Далее добавляем в /etc/exports имя экспортируемого каталога и перезагружаем демон монтирования:
# echo '/mnt' > /etc/exports
# /etc/rc.d/mountd onereload
Все, теперь хранилище доступно по сети и его можно подключить из Linux/FreeBSD с помощью одной команды:
# mkdir /mnt/server
# echo '192.168.1.100:/mnt /mnt/server nfs soft,intr,rsize=8192,wsize=8192' >> /etc/fstab
# mount -a
Вторая задача нашего сервера: качать файлы из интернета в автоматическом режиме. Для этого нужен торрент-клиент без графического интерфейса. На эту роль отлично подходит ctorrent, однако управлять закачкой файлов с помощью консольного интерфейса не всем по душе, поэтому мы воспользуемся более продвинутым решением под названием transmission-daemon, который сидит в фоне и принимает команды управления от удаленного клиента или через веб-интерфейс.
Веб-интерфейс Transmission
Он есть в репозитории прекомпилированных пакетов FreeBSD, поэтому установить и настроить его нетрудно:
# pkg_add -r transmission-daemon
Далее редактируем файл /etc/rc.conf, добавив в него следующие строки:
# Включаем transmission при загрузке
transmission_enable="YES"
# Каталог с конфигами
transmission_conf_dir="/usr/local/etc/transmission/"
# Каталог загрузок
transmission_download_dir="/mnt/torrents"
# Пользователь, с правами которого работает демон
transmission_user="transmission"
Создаем необходимые каталоги:
# mkdir /usr/local/etc/transmission
# chown -R transmission:transmission /usr/local/etc/transmission
# mkdir /mnt/torrents
# chown -R transmission:transmission /mnt/torrents
Создаем конфиг /usr/local/etc/transmission/settings.json:
{
/* Каталог для загрузки файлов */
"download-dir": "/mnt/torrents/",
/* Лимиты на скорость скачивания и отдачи. Отключены. */
"download-limit": 1000,
"download-limit-enabled": 0,
"upload-limit": 1000,
"upload-limit-enabled": 0,
/* Сохранять файлы с маской 022 (18 в десятичной системе),*/
/* что позволит читать их другим пользователям */
"umask": 18,
/* Настройка интерфейса удаленного доступа */
"rpc-authentification-required": 1,
"rpc-password": "ПАРОЛЬ",
"rpc-username": "ИМЯ_ПОЛЬЗОВАТЕЛЯ",
"rpc-whitelist-enabled": 0,
}
Наиболее важные в этом конфиге — последние четыре строки, они принуждают демон запрашивать права пользователя на управление. В домашней сети это может быть излишеством, так что их можно заменить на одну строку:
"rpc-authentification-required": 0,
После этого демон можно запустить:
# /usr/local/etc/rc.d/transmission start
И попробовать получить доступ к веб-интерфейсу: http://192.168.0.100:9091/transmission/web/. Также можно использовать удаленный клиент Transmission Remote GUI (goo.gl/YLHe) и один из многочисленных клиентов для Android.
Редактируем конфиг Transmission
Часть 5. Cron и все-все-все
Теперь, казалось бы, все работает. Сервер закачивает файлы с торрент-трекеров и благополучно отдает их другим машинам, но, во-первых, нужно следить за сервером (в особенности за забитостью файловой системы), а во-вторых — каким-то образом регулировать работу торрент-клиента, иначе он не даст спокойно работать в сети другим машинам. Для решения первой задачи я пошел по простому пути. Вместо использования различных тяжелых систем мониторинга, которые необходимо устанавливать и настраивать, я написал простой скрипт, который отдает нужную мне информацию о загруженности сервера и количестве свободного пространства в хранилище (температуру процессора, к сожалению, получить не удалось, поскольку на материнке нет нужных датчиков):
#!/bin/sh
FREE=`df -h /mnt | tail -n1 | column -t | cut -d ' ' -f 7`
LOAD=`uptime | cut -d ' ' -f 13-15`
echo $LOAD : $FREE
Скрипт возвращает примерно такую строку:
0.19, 0.13, 0.14 : 54G
Скрипт можно разместить на сервере и вызывать с помощью SSH:
$ ssh j1m@192.168.0.100 /home/j1m/bin/mon.sh
Причем вызывать не только руками, но и с помощью различных приложений, таких как монитор Conky или специальный виджет рабочего стола. Лично я настроил вывод этих данных в статусную строку менеджера окон i3. Для регулировки работы торрент-демона отлично подошел cron. В crontab-файл root'а (команда «crontab -e») я прописал три строки:
0 0 * * * /usr/local/etc/rc.d/transmission-daemon start
0 17 * * 1-5 /usr/local/etc/rc.d/transmission-daemon stop
0 10 * * 6-7 /usr/local/etc/rc.d/transmission-daemon stop
Этот crontab заставляет cron включать торрент-трекер в 12 ночи каждый день и отключать в 17:00 по будням и в 10:00 по выходным. Ты можешь подстроить его под свои вкусы и распорядок дня.
Франкенштейн в сборке
Выводы
Используя древнее железо и немного китайских деталек, я собрал вполне пригодный для моих личных нужд сервер хранения данных, который полностью удовлетворяет моим требованиям. Если у тебя дома есть старое железо, не спеши его выбрасывать или продавать. Старый системный блок можно превратить не только в NAS, но и в шлюз, медиасервер или даже игровой автомат для старых добрых 16- и 32-битных игр.
INFO
Для монтирования NFS в Android можно использовать бесплатное приложение СifsManager (требует root, но понимает как CIFS, так и NFS).