Настройка системы X-терминалов на базе Debian 3.1

В LXF номер 7 за 2006 год опубликована статья о том, как с помощью Linux создать учебный компьютерный класс на базе устаревших ПЭВМ. Вызывает однако сомнение простота настройки и администрирования системы в том варианте, который предлагается в той статье. В настоящей статье даются пошаговые инструкции, позволяющие получить работоспособную систему X-терминалов практически на любом оборудовании.

[Александр Чернышов (sch-ru AT yandex DOT ru)]

Введение

В LXF номер 7 за 2006 год опубликована статья о том, как с помощью Linux создать учебный компьютерный класс на базе устаревших ПЭВМ. Вызывает однако сомнение простота настройки и администрирования системы в том варианте, который предлагается в той статье. Достаточно вспомнить необходимость установки базовой системы Linux на каждый X-терминал, да ещё и с прописыванием ссылок на сервер в файловой системе на каждом рабочем месте.

В настоящей статье даются пошаговые инструкции, позволяющие получить работоспособную систему X-терминалов практически на любом оборудовании. В случае автора такая система работала в классе, состоящем из 14 компьютеров типа IBM PC 386/486 с одним средней мощности сервером (Pentium II, 96 Мбайт ОЗУ, 6 Гбайт винчестер, а первоначальный, экспериментальный вариант сервера имел всего 64 Мбайта ОЗУ и 2 Гбайт винчестер) и сетью 10 Мбит. Предлагаемый вариант позволяет вообще создать мобильный сервер, например на базе компьютера типа Notebook, который позволяет с минимальными усилиями (буквально в течение 10 минут чистого времени) запустить X-терминалы в любом компьютерном классе, оборудованном локальной сетью. При этом не потребуется трогать жёсткие диски на компьютерах класса, а значит установленный на них Windows со своим заклятым Microsoft Office (или что там ещё?) останется в целости и сохранности.

В общем идея работы класса та же самая, что и в прошлой статье. На рабочих станциях (X-терминалах) запущен X-сервер; все программы пользователей запускаются на сервере Linux, а окна свои выводят на соответствующий X-терминал и воспринимают ввод от мыши и клавиатуры с этого X-терминала (об этом как раз заботится X-сервер). Только теперь все каталоги пользователей и вообще вся корневая файловая система находятся на сервере Linux, монтируясь к X-терминалам по nfs. В результате каждый пользователь может свободно войти с любого X-терминала и получить доступ к своим файлам, да и ко всем программам, поскольку программы, установленные в системе и доступные пользователям суть программы установленные на сервере Linux.

Загрузка класса предельно проста. После загрузки сервера на каждом рабочем месте (будущем X-терминале) необходимо запустить ядро Linux, настроенное для загрузки по сети через nfs (о том, как это сделать, написано ниже). Вся остальная загрузка выполняется автоматически, и на экранах рабочих мест появляется графическое приглашение (login/password).

Для инсталяции потребуется компьютер сервера и дистрибутив Linux Debian 3.1. Терминальные компьютеры инсталировать не придётся. Вся инсталяция (и сервера класса, и конфигурирование терминальных компьютеров) выполняется на компьютере сервера. При инсталяции потребуется кое-где вводить IP-адреса сети. В данной статье предполагается, что для класса используется подсеть 10.1.1.X с маской 255.255.255.0, причём IP-адрес сервера 10.1.1.1.

Настройка сервера

Прежде всего, выполнить инсталяцию Debian обычным образом, установив минимум пакетов, но при этом не забыв настроить локаль и X (и с ним лучше icewm). Рекомендуется выполнять установку в режиме expert. Это позволит избежать установки лишних пакетов.

Сверх обычных пакетов необходимо установить OpenSSH (везде OK), xdm, nfsboot, gawk, nfs-kernel-server, (а для тех, кто знает, что делает, также pwgen, quota).

Все пакеты устанавливаются обычным образом через apt-get.

Корневой каталог пользовательской системы NFS разместим в отдельной файловой системе, расположенной в файле образа. Его размер 500 Мбайт (на установках автора реальная заполненность каталога 350 Мбайт):

dd if=/dev/zero of=/netrootimage bs=1024 count=524288
mke2fs /netrootimage
Будем располагать эту систему в каталоге /netroot
mkdir /netroot
Настраиваем её автоматическое монтирование - прописываем необходимую строку в файл /etc/fstab (как loop device):
/netrootimage	/netroot	ext2	loop	0	0
Если после этого не перезагружаемся, то выполняем монтирование вручную
mount -t ext2 -o loop /netrootimage /netroot
и создаём в нём клиентскую базовую систему.
Для этого:
  1. создаём пустые каталоги, в которые затем будем монтировать реальные - proc, usr, home, tmp (другие, вроде, не нужны)
    mkdir /netroot/usr
    mkdir /netroot/home
    mkdir /netroot/proc
    mkdir /netroot/tmp
    
  2. копируем каталоги системы верхнего уровня (за исключением созданных выше и некоторых необязательных)
    cp -a /bin /boot /dev /root /sbin /etc /lib /var /netroot
    
  3. копируем awk в /netroot/bin из /usr/bin (он нам понадобится при загрузке X-терминала до монтирования /usr)
    cp /usr/bin/gawk /netroot/bin
    ln -s /netroot/bin/gawk /netroot/bin/awk
    
  4. открываем на сервере каталоги для монтирования по NFS, прописав в /etc/exports строчки:
    /netroot *(rw,no_root_squash)
    /home *(rw,no_root_squash)
    /usr *(ro,no_root_squash)
    
  5. организуем вывод сообщений syslog'а в 8-ю консоль, добавив в файл /etc/syslog.conf строчку:
    *.*	/dev/tty8
    
  6. разрешаем демону syslogd принимать сообщения по сети. Для этого правим в файле /etc/init.d/sysklogd строку
  7. SYSLOGD=""
    
    на
    SYSLOGD="-r"
    
  8. Запрещаем xdm'у инициировать локальные X-серверы (нам не нужен X-терминал на сервере), закомментировав все строки в файле /etc/X11/xdm/Xservers (для некоторых версий xdm'а требуется явное указание на логины с других X-терминалов. В этот же файл добавить строки типа
    10.1.1.4:0 foreign
    
    для каждого X-терминала. Но для Debian 3.1 это не потребовалось).
  9. Разрешаем xdm'у инициировать логины со всех машин, прописав в файл /etc/X11/xdm/Xaccess строку
     *
    (один символ звёздочки)
    
  10. отключаем log'и xdm'а в консоль, подправив файл /etc/X11/xdm/Xsetup
  11. разрешаем в xdm попытки подключения - в файле /etc/X11/xdm/xdm-config надо закомментировать строчку
    DisplayManager.requestPort: 0
    
  12. Далее необходимо проверить запуск xdm. Встреченные в сети рекомендации указывают на файл /etc/inittab, но в Debian 3.1 достаточно проверить в /etc/rc2.d/ наличие линка, запускающего xdm. И обычно он там есть.

Настройка клиентской части на сервере

Все настройки выполняются в подкаталоге
/netroot
Для экономии памяти в etc/inittab оставляем только две консоли. Также инициируем запуск X-сервера:
10:23:respawn:/usr/bin/X11/X -query 10.1.1.1
                           ^        ^^^^^^^^
			   |        IP-адрес сервера
Запуск "чистого" X-сервера по полной конфигурации в файле etc/X11/*.conf

В файле конфигурации X-сервера необходимо задать правильный тип карты. Кроме того, проверить, что нет ограничения на глубину цветности (часто стоит максимальная глубина 24 bpp, что на старых компьютерах мешает получить хотя бы допустимые режимы и не позволяет запуститься X-серверу). Можно ограничиться типом "vesa", но это не всегда работает и не гарантирует хорошего результата. Для некоторых "клинических" случаев возможен тип "vga". Для карты nVIDIA необходимо указывать тип "nv" ("vesa" не работает).

Тип "vesa" рекомендуется для класса X-терминалов типа "солянка сборная". Он неплохо работает, если класс собран из ПЭВМ типа IBM PC 386/486 с видеокартами стандарта ISA с объёмом памяти 256-512 Кбайт. Но на этом типе драйвера практически невозможно "вытащить" высокие частоты вертикальных развёрток даже для тех случаев, когда аппаратура это позволяет. Если в классе однотипные видеокарты лучше поставить тип соответствующей карты и настроить нормальные частоты развёрток.

Из etc/rc2.d удаляем практически все скрипты (переводим их из S в K) за исключением

S10sysklogd
S11klogd
S99stop-bootlogd
В файле etc/default/rcS
DELAYLOGIN=no  #в старых системах было DELAYLOGIN=40
VERBOSE=no
EDITMOTD=no

Это именно для нормальных login'ов из текстовых (вторых) консолей. Попасть в эти консоли можно, нажав Ctrl+Alt+F2 на X-терминале. Интересно, что в этих консолях программы, запускаемые пользователями, загружаются с диска сервера, но, в отличие от графического окружения, выполняются на процессоре и памяти локального компьютера. Обратный переход в графику - кнопки Alt+F3.

При DELAYLOGIN=yes войти с текстовых консолей X-терминальных ПЭВМ сможет только root.

Для автоматического присваивания имени хоста в зависимости от IP-адреса клиента в файле etc/init.d/hostname.sh оставляем только одну строку:

hostname `/sbin/ifconfig eth0 | grep "inet addr" | 
	awk 'BEGIN{FS=".";}{printf "N%d",$4;}'`

Хосту будет присвоено имя типа Nx, где x - последняя цифра в IP-адресе хоста.

Если точно известна конфигурация дисков X-терминальных машин и на них мало ОП, то можно настроить инициализацию swap в файле etc/init.d/mountall

echo "Creating swap file..."
dd if=/dev/zero of=/mnt/swap0.swp bs=1024 count=16000
echo "Activating swap..."
mkswap /mnt/swap0.swp
swapon /mnt/swap0.swp

В этом случае всё-таки будет использоваться локальный диск рабочего места, но только в рамках его файловой системы. В данном случае файл свопинга будет создан на /dev/hda2 локального диска, что обычно соответствует диску D: в MS DOS. Для ПЭВМ с объёмом памяти 4-8 Мбайт создание файла свопинга необходимо.

Настраиваем отправку всех системных логов на сервер syslogd, а не в лог-файлы. Для этого в etc/syslog.conf оставляем только строчку:

*.*	@10.1.1.1
Для уменьшения времени загрузки системы в файле etc/network/options прописываем:
spoofprotect=no
В etc/init.d/sysklogd вставляем строчку, удаляющую /var/run/syslogd.pid (имея в виду, что он выше по файлу обозван $pidfile)
if [ -f $pidfile ]
	rm $pidfile
fi

Вообще желательно для каждого клиента создавать свой /var/run. Но у автора данной статьи всё работает и без этого.

Также необходимо при каждой загрузке удалять файл /netroot/tmp/.X0-lock Если файл не удалён, то новый X-сервер не сможет запуститься. А поскольку все X-серверы на всех терминальных ПЭВМ создают и проверяют один и тот же файл на сервере Linux, это может сорвать загрузку класса.

К счастью, в рассматриваемом дистрибутиве этот файл автоматически удаляется одним из стартовых скриптов. Поэтому, достаточно начинать загрузку каждого следующего компьютера через 10-15 секунд после предыдущего, а если для какого-то из X-терминалов загрузка X-сервера всё-таки сорвалась, достаточно просто нажать reset и повторить загрузку.

Настраиваем автоматическое монтирование компонентов для терминалов в клиентском /etc/fstab

10.1.1.1:/netroot	/	nfs	defaults	0	1
10.1.1.1:/usr		/usr	nfs	defaults	0	0
10.1.1.1:/home		/home	nfs	defaults	0	0
proc			/proc	proc	defaults	0	0

(ОСТАЛЬНЫЕ ЗАПИСИ ИЗ ЭТОГО ФАЙЛА УБРАТЬ!!!)
Если делаем свопинг, то
/dev/hda5		/mnt	umsdos	defaults	0	1
Если разрешаем работу с дисководом гибких дисков на локальной машине (только из второй, текстовой консоли), то
/dev/fd0		/floppy	auto	defaults,user,noauto 0	0
Проверяем в файле etc/network/interfaces отсутствие строчек про eth0 типа
eth0 auto
и дальше его принудительная настройка. Всё это надо ЗАКОММЕНТИРОВАТЬ!

Тонкая настройка сервера

  1. Для удобства заведения всех пользователей в одну группу исправить файл /etc/adduser.conf
    USERGROUPS = no
    USERS_GID = 1005
    
    "Скелет" домашнего каталога будущих пользователей находится в каталоге
    /etc/skel
    
    Его можно подправить, например
    cd /etc/skel
    mkdir WWW
    ln -s /home/public/ public
    
    В данном случае каждому пользователю создаётся каталог WWW для личных Web-страничек, а также ссылка public на каталог /home/public с методическими материалами, доступными только на чтение.
  2. Для корректировки вида экрана графического login'а править файл /etc/X11/xdm/Xresources (это в основном ресурсы программы xlogin) Так для отображения адреса X-терминала исправить строку
    xlogin*greeting: Debian GNU/Linux (CLIENTHOST)
    
    на
    xlogin*greeting: Debian GNU/Linux (SERVERHOST)
    

    Именно сервер, так как клиентский X-терминал для xdm и xlogin является сервером окон.

    Если после этого в качестве SERVERHOST отображается полный IP-адрес, то дописать в файл /etc/hosts строки типа

    10.1.1.2	N2	N2	N2
    10.1.1.3	N3	N3	N3
    и т.д.
    

    В файле Xresources также можно заменить картинку на окне xlogin'а. Эта картинка будет отображаться, если размер экрана X-сервера не менее 1024х768.

Сборка ядра клиента

Годится любое ядро, но желательно исходить из возможностей поддержки аппаратуры X-терминальных компьютеров. Так для IBM PC 386/486 с размером ОЗУ 4 Мбайт лучше всего выбрать ядро 2.0.X. Важно, чтобы версия ядра поддерживала корневой каталог на NFS. Если аппаратура позволяет, лучше взять ядро 2.6.15. Проблема - большой размер. Выигрыш - широкий выбор оборудования.

Если собирается ядро из имеющегося .config, то перед запуском

make menuconfig
сказать
make oldconfig

Очень важно включить поддержку NFS в файловых системах, далее в поддержке сети (вернуться) IP kernel level autoconfiguration и в открывшихся возможностях выбрать поддержку BOOTP и RARP. После этого в файловых системах выбрать поддержку корневого раздела на NFS.

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

Такое ядро, в принципе, даже влазит на дискету и загружается последней версией loadlin (что очень важно для старых компьютеров, не имеющих других внешних устройств, кроме дисковода 3,5").

ВНИМАНИЕ! В дистрибутиве Debian3.1 имеется loadlin с ошибками. Он такое ядро на загружает (хотя это обещано в его документации). "Правильный" loadlin имеется в комплекте следующего Debian'а, который на момент написания этого текста находится в состоянии test.

Для правильной (тестовой) загрузки ядру необходимо передать строку параметров типа

root=/dev/nfs nfsroot=/netroot ip=10.1.1.2:10.1.1.1::255.255.255.0:::
Имея в виду, что IP-адрес сервера 10.1.1.1

Варианты загрузки ядра на рабочих станциях

  1. Использование loadlin Вариант годится для устаревших ПЭВМ. В этом случае на жёсткий диск ставится MS-DOS и в её каком-нибудь подкаталоге кладутся ядро (bzImage), loadlin.exe и .bat файл с командой типа
    loadlin bzImage {далее полностью строка параметров ядра, данная выше}
    
    Необходимо проследить, чтобы на каждом клиенте был указан свой IP-адрес.

    Способ также годится для тестовой загрузки с дискеты. Для регулярной работы нежелателен - долго и ненадёжно. А также (при отсутствии HDD и необходимости загрузки с дискеты) необходимо для каждого клиента иметь свою дискету.

    Но можно заставить ядро брать IP по DHCP и обойтись всего одной дискетой (см. ниже).

    Если ядро не помещается на дискету вместе с MS DOS, можно loadlin и ядро записать на вторую дискету. Получится загрузочный комплект из двух дискет.

    • Возможна установка ядра + lilo на дискету безо всякого MS-DOS.
      Преимущество - нет "лишней" ОС - MS-DOS.
      Недостаток тот же.


      Способ автором статьи не тестировался, поэтому его описание опущено. При необходимости описание процесса подготовки дичкеты можно найти в сети.
    • Возможна установка на дискету ядра через syslinux.
      Этот способ лучше - значительно понятнее и без лишних файлов.
      Порядок следующий.
      • Готовим дискету. Если используется /dev/fd0, то достаточно просто её отформатировать в MS-DOS, например, через mformat
        mformat a:
        
        Если используется дисковод через USB (скажем, /dev/sda), то первоначально надо правильно дискету разметить (если она была отформатирована не в MS-DOS)
        fdisk /dev/sda
        
        и в нём выбрать режим "эксперт", а в нём правильно выставить: 2 головки, 80 дорожек (цилиндров), 18 секторов, (будет выдано сообщение о совместимости с fat/DOS - вообще полезно убедиться, что включён флаг совместимости с DOS) после чего вернуться в обычный режим. Создать единственный первичный раздел (первый, 1-80 единицы разметки) и сделать его типом FAT12.

        В mtools лучше настроить a: также и на /dev/sda (вернее, /dev/sda1). Далее
        mformat a:
        
      • Теперь монтируем дискету
        mount /dev/fd0 /mnt
        
        или
        mount /dev/sda1 /mnt
        
        и копируем на неё ядро (образ) и файл syslinux.cfg Содержание файла в зависимости от способа получения IP адреса см. ниже.
      • Далее
        umount /mnt
        
        и делаем
        syslinux -s /dev/fd0
        
        или
        syslinux -s /dev/sda
        
        Преимущество - нет "лишней" ОС - MS-DOS.
        Недостаток тот же.
  2. Использование flash-drive

    Реализуется загрузка самого ядра Linux посредством syslinux. Использовался syslinux-3.07. Требуется поддержка загрузки с USB в BIOS'е материнской платы. Наиболее рекомендуемый документацией режим загрузки "USB-HDD". Однако в документации не нашлось подробностей создания такого загрузочного flash. Зато нашлось предупреждение о том, что не во всех BIOS'ах этот режим корректно реализован. То есть он может не работать.

    Вместо него рекомендуется пробовать "USB-ZIP". В этом случае необходимо переразметить flash-drive под стандарт zip-drive (64 головки, 32 сектора) и установить загрузчик в раздел 4 этого диска.

    Делается это так:
    mkdiskimage -4 /dev/sda 0 64 32
    
    где 0 означает, что количество дорожек будет вычислено автоматически. Программа mkdiskimage имеется в составе syslinux. Далее
    syslinux /dev/sda4
    

    После чего необходимо смонтировать /dev/sda4 и записать в него обычным копированием образ ядра и файл конфигурации загрузки syslinux.cfg

    По умолчанию будет стартовать образ ядра с именем LINUX. Для изменения умолчания необходимо создать/отредактировать файл конфигурации загрузки syslinux.cfg. В него достаточно записать

    DEFAULT образ_ядра root=/dev/nfs nfsroot=/netroot ip=10.1.1.2:10.1.1.1::255.255.255.0:::
    
    Если ядро не будет найдено, будет выдано приглашение boot: но проблема в том, что в этот момент может ещё не работать клавиатура USB (если у компьютера именно она). Так что ввести что-либо будет проблематично.
    • flash-drive или CD-R с настройкой на автоматическое получение IP-адреса Для этого необходимо собрать терминальное ядро с поддержкой DHCP (это там же, где и BOOTP).

      В файл syslinux.cfg на загрузочном flash прописать строку
      DEFAULT образ_ядра root=/dev/nfs nfsroot=/netroot ip=dhcp
      
      А на сервере дополнительно установить сервер DHCP. Очень удобным оказался udhcpd, как лёгкий сервер, входящий в комплект Debian.
      apt-get install udhcpd
      
      Теперь необходимо его сконфигурировать. Создаём в /etc файл udhcpd.conf. Записываем в него строки
      start 10.1.1.2
      end 10.1.1.250
      interface eth0
      siaddr 10.1.1.1
      

      Начинаем с 10.1.1.2, так как сами мы 10.1.1.1 Конечный адрес пула - по усмотрению администратора. siaddr - адрес сервера для bootp протокола.

      Не забываем стартовать/рестартовать сервер udhcp.
  3. Использование возможности современных материнских плат - загрузка по сети (LAN BOOT).
    Для этого на сервере (в каталоге /):
    • установить atftpd через apt-get - на все вопросы ответить "Да", имя каталога /tftpboot;
    • создать каталог /tftpboot;
    • скопировать в него:
      	pxelinux.0 из комплекта syslinux
      	ядро (лучше сразу переименовать в linux - подробности читать
      		в pxelinux.doc)
      
    • создать каталог /tftpboot/pxelinux.cfg и создать в нём файл
      	default
      
      с параметрами загрузки - полный аналог файла syslinux.cfg из (2а) все пути к образу ядра в нём указываются относительно /tftpboot (подробности также в pxelinux.doc);
    • в файл /etc/udhcpd.conf добавить строку
      boot_file pxelinux.0
      
    • не забыть перезапустить udhcpd и установить в BIOS ПЭВМ терминалов загрузку по LAN (LAN PXE).

Заключение

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

Управлять системой довольно просто. Конфигурация клиентских машин, включая настройки X-сервера, содержится в каталоге /netroot/etc, конфигурация сервера Linux - в каталоге /etc. Для добавления новых программ их достаточно установить на сервер обычным образом (например, через apt-get). Доступность программ пользователям может регулироваться через меню и toolbar менеджера icewm, файлы конфигурации которого расположены по стандартному пути /etc/X11/icewm (в отличие от X-сервера, оконный менеджер, как и любая прикладная программа, стартует на сервере Linux).

На сервере полезно установить сервер WWW (Apache), СУБД (у автора стоит PostgreSQL), PHP. Сервер удобно подключить к принтеру и настроить систему коллективной печати, например через стандартный lpr. Естественно, при наличии соединения, возможен доступ в сеть Internet. Правда, для запуска тяжеловесных приложений всеми обучающимися (Mozilla, OpenOffice, Gimp и т.п.) требуется существенное увеличение ОЗУ на сервере. Но это общая проблема всех терминальных систем.

Автор выражает благодарность своим студентам Афонину Денису и Андриевскому Артёму, которые, используя разрозненные и далеко не полные статьи и свою смекалку, смогли запустить опытную первоначальную версию этой системы.

[ опубликовано 22/09/2006 ]

Александр Чернышов (sch-ru AT yandex DOT ru) - Настройка системы X-терминалов на базе Debian 3.1   Версия для печати