LaurVas

Ручная установка минимального Debian-based Linux (Install Debian the Archlinux way)

   linux debian

В данном руководстве описана установка Debian-based дистрибутива Linux (Debian, Ubuntu, Kali и др.) с нуля без использования каких-либо автоматических установщиков.

Цель ручной установки — минимизировать количество пакетов в системе, установить только то, что нужно. В какой-то момент понимаешь, что проще поставить систему с нуля, чем выпиливать лишнее из готовой. Какие преимущества это даёт перед традиционным способом установки?

  • Ручная установка поможет лучше узнать как работает ОС.
  • Экономится дисковое пространство, система занимает меньше места.
  • Обновления системы проходят быстрее, экономится трафик.
  • Бэкап системы занимает меньше места и быстрее разворачивается.
  • Вы знаете что есть в системе и для чего.
  • Загрузка из выключенного состояния проходит быстрее, т.к. не запускаются сервисы, о назначении которых вы ничего не знаете.
  • Поскольку лишних сервисов нет, ресурсы компьютера используются более рационально.

Тут мне надо написать абзац, чтобы отделить плюшки от оглавления. Пока ничего не придумал.

Нам понадобятся..

  1. Установка производится из другой работающей linux-системы. Это может быть livecd того же дистрибутива или уже установленная система, причём не обязательно debian-based. Главное — это наличие утилиты debootstrap в репозиториях. В Archlinux соответствующий пакет лежит в репозитории community, а в Gentoo называется dev-util/debootstrap. Устанавливать 32-битную систему можно как из 32-битной, так и из 64-битной. А вот 64-битную из 32-битной нельзя.
  2. Подключение к интернету во время установки.
  3. Отсутствие страха перед консолью.

Шаг 0. Подготавливаем и монтируем жёсткий диск

Чтобы сосредоточиться на установке и не описывать различные варианты разбиения жёсткого диска, я буду рассматривать простейший случай с одним единственным разделом на одном единственно диске, который мы целиком отдадим под новую систему и загрузчик. Это оптимальный вариант разбивки диска для использования под виртуальной машиной (VirtualBox, Qemu, VMware).

В случае установки на реальное железо надо соблюдать осторожность. Жёсткий диск как правило уже содержит какие-то разделы с ценной информацией. Возможно новая система будет соседствовать с другой ОС. При необходимости спланировать схему разбиения дисков обращайтесь к другим руководствам по установке Linux.

Можно не трогать жёсткий диск, а установить систему на флэшку или внешний жёсткий диск. В этом случае мы можем без опаски отдать под систему всё устройство целиком.

При создании виртуального диска сразу помечаем его как твердотельный, чтобы при удалении файлов его реальный размер уменьшался:

Создаём таблицу разделов и первый раздел

Для разметки диска можно использовать fdisk или графический gparted. Я использую parted, потому что им удобно пользоваться в неинтерактивном режиме.

Прежде чем вводить эти команды, проверьте, что на размечаемом диске нет ничего ценного! Я не несу ответственности за ваши потерянные данные!

# parted -s /dev/sdX mklabel msdos
# parted -s /dev/sdX -- mkpart primary ext2 1MiB -1s

Вместо sdX должно быть sda, sdb, sdc и т.д, смотря сколько дисков подключено и на какой вы хотите установить систему. Команда lsblk покажет информацию обо всех дисковых устройствах, подключенных в настоящий момент.

Первая команда создаёт таблицу разделов MBR (не GPT). Вторая команда создаёт раздел, смещённый относительно начала диска ровно на 1 МБ (т.н. “выравнивание” раздела) и заканчивающийся последним сектором (-1s). Нумерация секторов начинается с нуля. Ключ -- означает, что дальше аргументов не будет и нужен для правильного восприятия -1s.

Информация о разделе записана в таблицу разделов MBR, но файловой системы на нём ещё нет. ext2 во второй команде — это только тип раздела — однобайтный идентификатор, записываемый в таблицу разделов MBR. У файловых систем ext2/3/4 идентификатор одинаковый и равен 0x83.

Хорошая подсказка по идентификаторам есть в утилите fdisk:

# echo l | fdisk /dev/sdX

На всякий случай проверим выравнивание (последняя цифра — номер раздела):

# parted /dev/sdX align-check opt 1

Форматируем раздел

В качестве файловой системы будем использовать Ext4. Это хорошая, стабильная файловая система. Я вижу два существенных преимущества Ext4 по сравнению с Ext2 и Ext3:

  • возможность эффективного хранения разреженных (sparse) файлов,
  • поддержка ATA-команды TRIM. Она не даст виртуальному диску распухать со временем.
# mkfs.ext4 -m 1 /dev/sdX1 -L debian
или
# mkfs.ext4 -m 1 -O ^has_journal /dev/sdX1 -L debian

-m 1 — зарезервировать 1% пространства под нужды суперпользователя (по умолчанию 5%).
-L debian — метка (label) раздела. Выбирайте на свой вкус.
-O ^has_journal отключает журналирование на ФС. Отсутствие журнала немного увеличивает производительность, но может привести к нарушению целостности ФС при внезапном отключении питания.

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

# mkdir /mnt/sdX1 && mount /dev/sdX1 /mnt/sdX1

Шаг 1. Debootstrap

Debootstrap разворачивает в указанном каталоге минимальный набор пакетов, необходимый для самостоятельной работы системы. Это самый важный шаг. Если сейчас допустить ошибку, то всё придётся переделывать сначала. Инструкцию я вынес в отдельный пост debootstrap.

Рекомендую сделать бэкап сразу после этого шага. Я устанавливаю Debian Jessie, поэтому мои бэкапы содержат jessie в названии. Команды подсмотрены в Ubuntu community help wiki.

# tar cpzf /path/to/jessie-debootstrapped.tar.gz --one-file-system -C /mnt/sdX1 .
или
# tar cpjf /path/to/jessie-debootstrapped.tar.bz2 --one-file-system -C /mnt/sdX1 .
или
# tar cpJf /path/to/jessie-debootstrapped.tar.xz --one-file-system -C /mnt/sdX1 .

Наибольшее сжатие будет у .tar.xz архива, самое быстрое у tar.gz. Посередине находится tar.bz2. У меня в цифрах получилось так:

Сжатие Размер архива, MiB Время компрессии, с
gzip 91 7.5
bzip2 83 16.6
xz 68 68.2

Восстановление из бэкапа:

# find /mnt/sdX1 -delete
# tar xpf /path/to/backup.tar.gz -C /mnt/sdX1 --numeric-owner
или
# tar xpf /path/to/backup.tar.bz2 -C /mnt/sdX1 --numeric-owner
или
# tar xpf /path/to/backup.tar.xz -C /mnt/sdX1 --numeric-owner

Шаг 2. Вход в систему (chroot)

Чтобы процессы из chroot-окружения могли общаться с ядром, необходимо примонтировать псевдо-файловые системы /proc, /sys, /dev:

# cd /mnt/sdX1
# mount proc -t proc ./proc
# mount sys -t sysfs ./sys
# mount --bind /dev ./dev
# mount --bind /dev/pts ./dev/pts

/dev/pts — виртуальная файловая система, которая динамически создаёт файлы терминалов /dev/pts/X для каждого нового подключения. Это необходимо для нормального функционирования многих программ, работающих с терминалом, в т.ч. скриптов debconfig.

После того, как всё необходимое смонтировано, делаем chroot “в туда”

# chroot /mnt/sdX1 /bin/bash

Стоп, так делать не надо. Такой чрут потянет за собой переменные окружения из внешней системы (проверяется командой env). Вот правильный чрут:

# chroot /mnt/sdX1 /usr/bin/env -i HOME=/root TERM="$TERM" /bin/bash --login

Всё, мы внутри! В дальнейшем по тексту я буду отмечать чрутовый шелл приглашением (chroot)#.

Можно ли поиметь сразу несколько терминалов в одном chroot-окружении? Да, просто делаем ещё один точно такой же чрут и получаем второй терминал. Повторно монтировать ничего не надо.

Шаг 3. Первичная настройка системы

Задаём пароль рута:

(chroot)# passwd

Устанавливаем часовой пояс:

(chroot)# ln -sf /usr/share/zoneinfo/UTC /etc/localtime
или
(chroot)# ln -sf /usr/share/zoneinfo/Europe/Moscow /etc/localtime

Задаём имя хоста, в моём случае — debian-pc:

(chroot)# echo "debian-pc" > /etc/hostname

также прописываем имя хоста в /etc/hosts для адреса 127.0.0.1 после localhost:

(chroot)# echo 127.0.0.1 localhost debian-pc > /etc/hosts
(chroot)# echo ::1 localhost debian-pc >> /etc/hosts

Если этого не сделать, то имя debian-pc не будет резолвится в IP-адрес, и вы не сможете себя попинговать :)

Сеть должна работать без дополнительных манипуляций. Проверяем:

(chroot)# apt update

Если возникли проблемы с DNS, берём /etc/resolv.conf с основной системы:

# cp /etc/resolv.conf /mnt/sdX1/etc/resolv.conf

Устанавливаем локаль:

(chroot)# apt install locales

(chroot)# echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen
(chroot)# locale-gen
(chroot)# update-locale LANG=en_US.UTF-8
  • Вы можете не использовать echo, а раскомментировать необходимые локали в /etc/locale.gen вручную.
  • Вместо en_US.UTF-8 можно прописать ru_RU.UTF-8, тогда всё будет по-русски.
  • Последние 3 команды можно заменить интерактивной dpkg-reconfigure locales.

Проверяем список доступных локалей и текущую локаль:

(chroot)# locale -a
(chroot)# locale

Создаём fstab

В случае с одним единственным разделом можно обойтись без fstab, т.к. корневую ФС ядро само примонтирует, а больше ничего монтировать не требуется. Однако:

  • Корневая ФС не будет видна в выводе команды mount и в /etc/mtab. В /proc/mounts по-прежнему видна.
  • Ядро будет монтировать корень с дефолтными параметрами, что не всегда приемлемо. Можно поменять параметры монтирования по-умолчанию и всё равно обойтись без fstab. Вот я сейчас включу discard:
# tune2fs -o discard /dev/sdX1
# tune2fs -l /dev/sdX1 | grep "^Default mount"

Однако не все параметры монтирования можно прописать как дефолтные напрямую в ФС (см. man tune2fs). У меня не получись вписать relatime, поэтому таки пришлось создать fstab:

(chroot)# echo "/dev/sdX1 / ext4 defaults,relatime,discard,barrier=0 0 1" > /etc/fstab

Вместо /dev/sdX1 надёжнее вписать UUID файловой системы. Узнать его можно командой blkid /dev/sdX1. При использовании UUID запись в fstab будет выглядеть примерно так:

/etc/fstab
UUID=3868a282-bd3a-4d9c-9902-72a740aabf80 / ext4 defaults,relatime,discard,barrier=0 0 1

Опция монтирования discard нужна если наш носитель является твердотельным. Опции relatime и barrier=0 немного повышают производительность ФС.

Конфигурируем менеджер пакетов

При необходимости добавляем репозитории, указываем локальное зеркало и т.д.

/etc/apt/sources.list для Debian Squeeze
deb http://archive.debian.org/debian squeeze main contrib non-free
deb http://archive.debian.org/debian-security squeeze/updates main contrib non-free
deb http://archive.debian.org/debian squeeze-lts main contrib non-free
# deb http://archive.debian.org/backports.org squeeze-backports main contrib non-free
/etc/apt/sources.list для Debian Wheezy
deb http://mirror.yandex.ru/debian wheezy main contrib non-free
deb http://mirror.yandex.ru/debian-security wheezy/updates main contrib non-free
deb http://mirror.yandex.ru/debian wheezy-updates main contrib non-free
# deb http://mirror.yandex.ru/debian wheezy-backports main
/etc/apt/sources.list для Debian Jessie
deb http://mirror.yandex.ru/debian jessie main contrib non-free
deb http://mirror.yandex.ru/debian-security jessie/updates main contrib non-free
deb http://mirror.yandex.ru/debian jessie-updates main contrib non-free
# deb http://mirror.yandex.ru/debian jessie-backports main
/etc/apt/sources.list для Ubuntu Precise Pangolin
deb http://mirror.yandex.ru/ubuntu precise main multiverse restricted universe
deb http://mirror.yandex.ru/ubuntu precise-security main multiverse restricted universe
deb http://mirror.yandex.ru/ubuntu precise-updates main multiverse restricted universe
/etc/apt/sources.list для Ubuntu Trusty Tahr
deb http://mirror.yandex.ru/ubuntu trusty main multiverse restricted universe
deb http://mirror.yandex.ru/ubuntu trusty-security main multiverse restricted universe
deb http://mirror.yandex.ru/ubuntu trusty-updates main multiverse restricted universe
/etc/apt/sources.list для Ubuntu Xenial Xerus
deb http://mirror.yandex.ru/ubuntu xenial main multiverse restricted universe
deb http://mirror.yandex.ru/ubuntu xenial-security main multiverse restricted universe
deb http://mirror.yandex.ru/ubuntu xenial-updates main multiverse restricted universe
/etc/apt/sources.list для Kali Sana
deb http://old.kali.org/kali sana main contrib non-free
deb http://old.kali.org/kali-security sana/updates main contrib non-free
/etc/apt/sources.list для Kali Rolling
deb http://http.kali.org/kali kali-rolling main non-free contrib

Спортсмены отключают установку рекомендованных пакетов:

(chroot)# echo 'APT::Get::Install-Recommends "false";' >>/etc/apt/apt.conf
(chroot)# echo 'APT::Get::Install-Suggests "false";' >>/etc/apt/apt.conf

Шаг 4. Устанавливаем ядро

Наша новая система может работать в chroot-окружении, но ещё не способна самостоятельно загружаться. Потому что ни загрузчика нет, ни ядра (да-да, тот самый Linux).

Выясним какие ядра доступны в репозиториях:

(chroot)# apt search linux-image
или
# chroot /mnt/sdX1 apt search linux-image

Посмотреть описание конкретного пакета можно командой

(chroot)# apt show linux-image-686
или
# chroot /mnt/sdX1 apt show linux-image-686

Ну и устанавливаем понравившееся:

(chroot)# apt install linux-image-686

В каталоге /boot появился образ ядра. Запоминаем его название, скоро пригодится.

(chroot)# ls /boot/vmlinuz*

Шаг 5. Устанавливаем загрузчик

У нас есть ядро, но его кто-то должен загрузить в оперативную память компьютера и передать управление. Этим занимается загрузчик. Обычно ставят GRUB2, но мне больше нравится Syslinux. Ещё есть LILO.

Поскольку загрузчик никак не используется после загрузки Linux, и мы стремимся минимизировать количество пакетов в системе, я буду устанавливать загрузчик из внешней системы.

# mkdir /mnt/sdX1/boot/syslinux
# extlinux -i /mnt/sdX1/boot/syslinux
# dd if=/usr/lib/syslinux/bios/mbr.bin of=/dev/sdX bs=440 count=1
# cp /usr/lib/syslinux/bios/{ldlinux.c32,libcom32.c32,libutil.c32} /mnt/sdX1/boot/syslinux

В зависимости от дистрибутива Linux и версии загрузчика могут различаться пути к запчастям загрузчика (вот этот /usr/lib/syslinux/bios). Команды в помощь:

# find / -name ldlinux.c32 2>/dev/null
# find / -name mbr.bin 2>/dev/null

Создадим минимальный конфиг загрузчика: без меню, без графики, лишь бы ядро загружалось.

/mnt/sdX1/boot/syslinux/syslinux.cfg
PROMPT 0
DEFAULT 686

LABEL 686
    LINUX ../vmlinuz-2.6.32-5-686
    APPEND root=UUID=3868a282-bd3a-4d9c-9902-72a740aabf80 rw
    INITRD ../initrd.img-2.6.32-5-686

После LINUX указывается путь к ядру Linux.
После APPEND перечисляются параметры загрузки ядра (Kernel boot parameters).
После INITRD указывается путь к начальному рам-диску. Начальный рам-диск лежит в том же каталоге, что и ядро.

Подробнее о загрузчике см. арчвики, там хорошо написано.

Осталось включить boot-флаг в MBR:

# parted -s /dev/sdX set 1 boot on

Шаг 6. Перезагружаемся!

Осталось закрыть все чруты, размонтировать файловую систему и загрузиться с носителя.

(chroot)# exit
# cd /mnt
# umount ./proc ./sys ./dev/pts ./dev
# reboot

Если загрузка прошла успешно, то появится приглашение залогиниться. Проверяем пароль рута, перезагружаемся и делаем новый бэкап:

# mkdir /mnt/sdX1 && mount /dev/sdX1 /mnt/sdX1
# cd /mnt/sdX1
# tar cpJf jessie-configured.tar.xz --exclude='./var/cache/apt/archives/*.deb' \
--exclude='./var/lib/apt/lists/*' --exclude='./var/cache/apt/*.bin' \
--one-file-system -C jessie .

Чтобы архив занимал меньше места, мы исключаем:
/var/cache/apt/archives/*.deb — кэш deb-пакетов apt’а
/var/lib/apt/lists/* — сохранённые индексы репозиториев (что лежит в таком-то репозитории)
/var/cache/apt/*.bin — какая-то база данных apt’а

Вот собственно и всё — минимальный Debian готов!

Если возникают проблемы с загрузкой, то снова загружаемся в большую систему, монтируем носитель, монтируем ФС /dev/, /proc, /sys, чрутаемся внутрь и вносим исправления.

Шаг 7. Доведение до ума

Дополнительные пакеты, которые могут понадобиться:
cron — планировщик задач
dhcpcd позволит получать настройки сети автоматически по протоколу DHCP
file — утилита для определения типа файла
iproute — набор утилит для управления сетевыми подключениями
less — утилита просмотра текста с возможностью скроллить вверх и вниз
logrotate
nano — простенький консольный текстовый редактор
ncurses-term для поддержки терминала rxvt-unicode-256color и других
ntp — сервис точного времени
openssh-server
rsync для синхронизации файлов и каталогов
sudo
vim или vim-tiny
zsh

Напоминаю, что посмотреть описание пакета можно командой

(chroot)# apt show ПАКЕТ

Создаём пользователя vas, входящего в группу sudo. Вы можете создать другого :)

(chroot)# useradd -m -g users -G sudo -s /usr/bin/zsh vas
(chroot)# passwd vas

Иногда бывает удобно сделать sudo без ввода пароля. На хостовой системе я себе таких шалостей не позволяю, а в контейнере можно. Не редактируйте /etc/sudoers напрямую! Используйте команду visudo.

Разрешаем sudo без пароля для всех пользователей, входящих в группу sudo:

/etc/sudoers
%sudo    ALL=(ALL:ALL) NOPASSWD:ALL

В качестве вишенки на торте возьмём zshrc, vimrc и т.п. с хостовой системы.

Можно немного облегчить систему за счёт man-страниц, документации, локалей. Это для особо целеустремлённых спортсменов.

(chroot)# rm -rf /usr/share/doc/*
(chroot)# find /usr/share/locale -maxdepth 1 -mindepth 1 ! -name en_US -exec rm -rf {} \;
(chroot)# find /usr/share/i18n/locales -maxdepth 1 -mindepth 1 ! -name en_US -exec rm -rf {} \;
(chroot)# rm -rf /usr/share/man/*
(chroot)# rm -rf /usr/share/groff/*
(chroot)# rm -rf /usr/share/info/*
(chroot)# rm -rf /usr/share/lintian/*
(chroot)# rm -rf /usr/include/*

Вот собственно и всё!