From: Алексей Кеда (lissyara) <admin@lissyara.su.>
Date: Mon, 25 Nov 2007 18:21:07 +0000 (UTC)
Subject: Бездисковые терминалы на FreeBSD
Оригинал: http://www.lissyara.su/?id=1191
Итак, немного предыстории. Две довольно большие конторы, и одна
маленькая. Один домен на всех, общая локалка. Всё хорошо, но конторы
надо разделать, по техническим и политическим причинам. Примерно 40
человек работали в терминале. С ними и произошли проблемы -
использовался линуксовый тонкий клиент - достался по наследству, и при
переключении клиентов в другую сеть, они потеряли свои конфиги.
Копание в скриптах клиента ничего не дало - везде поменял одну сеть на
другую, но бестолку. Сидеть и подробно разбираться в чужом творении -
откровенно не хотелось. Да и не люблю я пингвинов, наверно, потому,
что готовить не умею :))
Изыскания на сайте FreeBSD привели к хандбуку. Согласно нему,
всё было просто. В общем-то, так и оказалось. На 6-й ветке тонкий
клиент завёлся и заработал влёт, но был косяк - у меня много старых
машин, и старых сетевух - они грузились по сети с дискеток, а не с
PXE-биоса сетевухи. Как оказалось, нету ни одной дискеты, которая
могла бы загрузить и переварить лоадер FreeBSD. Ближе всех к истине
оказался microsoft - у них есть загрузочная дискета для удалённой
установки, оно грузило, запускало, но как-то неправильно передавала
параметры - лоадер не получал адреса сервера и своего IP....
Помучавшись несколько дней, пришёл к выводу - с дискеты надо
грузить ядро фряхи, и корневую ФС, остальное монтировать с сети. Тока
вот в 6-й ветке, мне так и не удалось ужать ядро и корневую ФС с
уилитами до приемлемого размера. Пришлось собирать тестовую машину,
ставить 4-ю ветку. Там всё получилось, и, как выяснилось, на дискету
достаточно положить только ядро :)))
Итак. Ставим ОСь, обновляем исходные тексты системы,
пересобираем мир, ядро. Пишем примерно такой конфиг ядра (для 4.11 -
на 6.0 отличия минимальные, и всё одинаково хорошо работает и в одной
и в другой ветке.)
# ядро не обязательно делать именно таким.
# Просто, чем оно меньше будет, тем быстрей будут грузиться
# клиенты. Юзеры - народ нервный :)))
machine i386
cpu I586_CPU
cpu I686_CPU
ident diskless-1
maxusers 0
options MATH_EMULATE
options INET
options FFS
options FFS_ROOT
options SOFTUPDATES
options MFS
options MD_ROOT
options NFS
options NFS_ROOT
options PROCFS
options COMPAT_43
device isa
device eisa
device pci
device fdc0 at isa? port IO_FD1 irq 6 drq 2
device fd0 at fdc0 drive 0
device atkbdc0 at isa? port IO_KBD
device atkbd0 at atkbdc? irq 1 flags 0x1
device psm0 at atkbdc? irq 12
device vga0 at isa?
device sc0 at isa? flags 0x100
device agp
device npx0 at nexus? port IO_NPX irq 13
device apm0 at nexus? disable flags 0x20 # Advanced Power Management
device de
device em
device txp
device vx
device miibus
device dc
device fxp
device pcn
device rl
device sf
device sis
device ste
device tl
device tx
device vr
device wb
device xl
device bge
device ed0 at isa? disable port 0x280 irq 10 iomem 0xd8000
device ex
device ep
device fe0 at isa? disable port 0x300
device xe
pseudo-device loop
pseudo-device ether
pseudo-device pty
pseudo-device md
# следующие строки добавлял я - до этого момента лишь убирал лишнее
# цвет консоли - кому как удобней, и буфер консоли
options SC_NORM_ATTR=(FG_GREEN|BG_BLACK)
options SC_KERNEL_CONS_ATTR=(FG_RED|BG_BLACK)
options SC_HISTORY_SIZE=2022
# как раз опции для поддержки бездисковых клиентов
options BOOTP
options BOOTP_NFSROOT
options BOOTP_COMPAT
Расписывать какая опция за что отвечает - не буду, это уже
было. Конфиг обзываем, например, main-diskless. Добавляем такую
строчку в /etc/make.conf:
# Опция необязательная, нужна для загрузки ядра по TFTP а не по NFS.
# Я захотел сдеть так, вы - можете иначе.
LOADER_TFTP_SUPPORT=YES
mkdir -p ${DESTDIR} &&
cd /usr/src && make cleandir && make clean && make cleandir && make clean &&
make world DESTDIR=${DESTDIR} &&
cd /usr/src/etc &&
make distribution DESTDIR=${DESTDIR} &&
cd /usr/src &&
make kernel DESTDIR=${DESTDIR} KERNCONF=${kernell_config} &&
echo "Building Completed"
Ну, и сделав его исполняемым, запускаем. Ждём завершения работы, в
указанной директории (/usr/local/tftp/freebsd.4.11 - но можно и
поменять, в скрипте) должна появиться вся система, и ядро. По
окончании работы скрипта, советую проверить наличие и того, и другово.
Пока собирется мир и ядро, организуем сервер tftp, раскомментив и
слегка подправив строчку в /etc/inetd.conf:
# Следующие две строки - на самом деле - одна, просто у меня не влезли.
tftp dgram udp wait root /usr/libexec/tftpd
tftpd -l -s /usr/local/tftp/freebsd.4.11 -u root
Даём команду inetd перечитать свой конфиг (если он у вас запущен и
работает. Если не запущен, смотрите тут)
/usr/home/lissyara/>killall -1 inetd
Если есть желание логгировать запросы к tftpd, добавляем в
/etc/syslog.conf такие строки:
# TFTPd
!tftpd
*.* /var/log/tftpd.log
Затем создаём файлик и даём команду syslogd перечитать свой конфиг:
Также, нам необходимо организовать расшаривание создаваемой
корневой системы по NFS, для этого, добавляем такие строки в
/etc/rc.conf (значение опций можно посмотреть тут)
Также расшариваем будущую корневую ФС тонких клиентов, для этого
вносим в файл /etc/exports такие строки:
# То, что расшариваем по NFS
/usr/local/tftp/freebsd.4.11 -maproot=root -network 192.168 -mask 255.255.0.0
На первый раз, можно запустить руками, или перезагрузиться, если
мир с ядром уже собрались и проинсталлились. Если будте запускать
руками, то я использую такой скрипт (вообще, он для перезапуска, чё-то
у меня не получается штатными средсвами перезапустить всю эту кучу
демонов, если правил /etc/exports)
Ну, перезупускаем dhcp, и если мир с ядром установились, пробуем
загузиться с машины подерживающей PXE. Должно получиться. Правда, сам
клиент будет по мелочи ругаться - sendmail и прочие не запустятся.
Также надо сразу подправить файл
/usr/local/tftp/freebsd.4.11/etc/fstab до такого состояния:
# fstab for diskless clients
# Корневая система в режиме только чтение (пока в rw укажите, потом смените,
# после окончательной настройки)
192.168.110.254:/usr/local/tftp/freebsd.4.11 / nfs ro 0 0
# дерево портов. Можно пользоваться и локальным - кому как удобней.
192.168.110.254:/usr/ports /usr/ports nfs rw 0 0
Собственно, дальнейшие работы я производил с тонкого клиента (ага,
загрузившись по сети на двухголовом ксеноне с гигабитной сеткой и 3Gb
памяти :)))) - надо писать конфиги, и устанавливать иксы, ибо целью
было, не посадить юзеров за консоль FreeBSD, а подрубить их к
виндовому серверу терминалов. Есть и другой метод - jail - можно
на родительской машине зайти в корневую директорию для клиентов, как в
клетку. Но - мне этот мето не подходил - я экспортировал с 6-й
FreeBSD, а на клиентах была 4.11 (перенёс с машины на машину tar`ом).
Посему ищем самую мощную доступную машину, и грузимся с неё.
Для начала, надо передвинуть с /var всё, что нужно, т.к. на тонком
клиенте /var находитя в оперативной памяти (надо сказать такую феню -
если / смонтировать в режиме чтения-записи, то /var, /tmp и /dev не
создаются в оперативке, а вот если всё в режиме только чтения - фря
создаёт их в оперативке), а собсно из родного /var нам надо лишь
/var/db/pkg который мы переместим в /usr/local/var/db/pkg. Для этого,
надо завести переменную окружения $PKG_DBDIR. Для этого, правим файл
/root/.cshrc, вносим в его начало такую строчку:
setenv PKG_DBDIR /usr/local/var/db/pkg
Всё путём. Можно собирать из портов ПО. Нa 4.11 (на шохе - влёт) у
меня не собрался xorg - но я и не особо пытался, посему собираем
XFree4. C ним тоже не всё гладко, поэтому добавляем в /etc/make.conf
такие строки:
# Опция необязательная, нужна для загрузки ядра по TFTP а не по NFS.
# Я захотел сдеть так, вы - можете иначе.
# заметтьте - тут эта опция потому, что я пересобирал ядро с
#тонкого клиента, у которого свой конфиг.
LOADER_TFTP_SUPPORT=YES
# опции касающиеся иксов
InstallAppDefFiles= NO
InstallXdmConfig= NO
HasSecureRPC= NO
HasPam= NO
После чего, собираем такой список софта:
XFree86-Server-4.5.0_4 XFree86-4 X server and related programs
XFree86-clients-4.5.0_3 XFree86-4 client programs and related files
XFree86-fontDefaultBitmaps-4.5.0_1 XFree86-4 default bitmap fonts
XFree86-fontEncodings-4.5.0_1 XFree86-4 font encoding files
XFree86-libraries-4.5.0 XFree86-4 libraries and headers
expat-2.0.0_1 XML 1.0 parser written in C
fontconfig-2.3.2_6,1 An XML-based font configuration API for X Windows
freetype2-2.2.1_1 A free and portable TrueType font rendering engine
gettext-0.14.5_2 GNU gettext package
gmake-3.81_1 GNU version of 'make' utility
imake-4.5.0 Imake and other utilities from XFree86
ldconfig_compat-1.0_8 Ldconfig compatibility script
libXft-2.1.7_1 A client-sided font API for X applications
libiconv-1.9.2_2 A character set conversion library
libtool-1.5.22_2 Generic shared library support script
pkg-config-0.21 A utility to retrieve information about installed libraries
png-1.2.12_1 Library for manipulating PNG images
rc_subr-1.31_1 Common startup and shutdown subroutines used by scripts
rdesktop-1.5.0 RDP client for Windows NT/2000/2003 Terminal Server
xfree86-dri-4.5.0 OpenGL hardware acceleration drivers for XFree86
xterm-222 Terminal emulator for the X Window System
Я собирал вначале rdesktop, а уже затем всё оставшееся (осталось
то, что начиналось на заглавную букву X :)). Пока собирается ПО,
настраиваем систему - я настроил русскую локаль, и привёл
/etc/rc.conf к такому состоянию:
# Русский язык в консоли
font8x14="cp866-8x14"
font8x16="cp866b-8x16"
font8x8="cp866-8x8"
scrnmap="koi8-r2cp866"
# Запускаем sshd для удалённого доступа к клиентам
sshd_enable="YES"
# Убираем запуск sendmail (я вообще поставил на тонких клиентов exim :))
sendmail_enable="NONE"
# Включаем syslogd (пусть месаги всякие пишет)
syslogd_enable="YES"
# включаем крон - я установил /usr/ports/sysutils/bsdstats и настроил на
# запуск днём - нехай в России будет больше фрях :))
cron_enable="YES"
# Размер /var для бездисковой станции (в 512-байтных блоках!)
varsize="6144" # У меня - 3 мегабайта
# Опции касающиеся мыши. У мeня у всех PS/2
moused_enable="YES"
moused_type="auto"
moused_port="/dev/psm0"
# Используемые в иксах переменные:
# ${x_keyboard} - модель клавы
# ${x_mouse_proto} - протокол мыши
# ${x_mouse_device} - устройство мыши
# ${x_horiz_sync} - горизонтальная развёртка
# ${x_vert_refresh} - частота обновления кадров
# ${x_vga_driver} - драйвер видеокарты
# ${x_color_bits} - скольки битный цвет в иксах
# Ввиду того, что по DHCP клиент не получает DNS-сервер,
# указываем его тут
dns_server_ip="192.168.0.254"
# сервер времени в локальной сети (у меня много старых компов с чуть живыми
# батрейками, а F1 юзеры уже давно сами нажимать научились :))
local_ntp_server="192.168.0.253"
# Имя пользователя, от которого будут работать иксы.
x_username="ThinUser"
x_user_profile_dir="/var/user_profile"
users_configs_dir="/usr/local/etc/thin_configs"
# Если завершение работы - ничё не делаем.
case "$1" in
stop)
# нихрена не делаем :)
# Просто, без этого пункта, при остановке тонкого клиента,
# снова запускаются иксы
;;
# Если старт - запускаем rdesktop
start)
# синхронизируем время на клиенте (в фоне, т.к.
# сервер может вообще не ответить)
ntpdate -b ${local_ntp_server} &
# Вытаскиваем персональные настройки клиента.
# Определяем его MAC-адрес
client_mac=`ifconfig | grep ether | awk '{print $2}' |
tr -d ":" | tr "[:lower:]" "[:upper:]" | tail -1`
# Инклюдим персональный конфиг клиента, если он сущствует
if [ -s ${users_configs_dir}/${client_mac}.conf ]
then
. ${users_configs_dir}/${client_mac}.conf
else
. ${users_configs_dir}/defaults.conf
fi
# Стругаем директорию, где будет лежать конфиг иксов
mkdir -p /var/etc/X11
rm -R /etc/X11 >/dev/null 2>&1
ln -s /var/etc/X11 /etc/X11 >/dev/null 2>&1
# Глобальная конфигурация - создаём пользовательский конфиг
# иксов из шаблона - xorg.conf.template
. ${users_configs_dir}/conf/xorg.conf.template
# На этом этапе можно подрубить swap - если на клиентах мало памяти.
# Выглядеть это будет примерно так (где /swap смонтирована с машины
# на которой расшарена директория с правами на запись по NFS
# if [ ! -s /swap/${client_mac}.swp ]
# then
# echo "Adding SWAP file...."
# dd if=/dev/zero of=/swap/${client_mac}.swp bs=1m count=128
# swapon /swap/${client_mac}.swp
# else
# echo "Adding SWAP file...."
# swapon /swap/${client_mac}.swp
# fi
# Запускаем бесконечный цикл
${users_configs_dir}/conf/rdesktop_polling.sh ${win_user_name}
${win_ts_server} ${x_user_profile_dir} ${x_username} &
# Валим %)
exit;
. /usr/local/etc/thin_configs/conf/thin_startup.sh
# конец скрипта
;;
# Запускаем бесконечный цикл
while test 1 -eq 1
do
# считаем число процессов rdesktop.
rdesktop_proc="`ps -ax | grep rdeskt | grep -v grep |
grep -v '/bin/sh' | wc -l`"
# ПРоверяем, работает ли rdesctop
if [ ${rdesktop_proc} -ne 1 ]
then
# создаём файл .xinitrc
echo "exec /usr/local/bin/rdesktop
-u ${win_user_name} -n ${win_user_name}
-d grand-prix -f -N ${win_ts_server}" >
${x_user_profile_dir}/${x_username}/.xinitrc
# Даём на неё ему права
chown ${x_username} ${x_user_profile_dir}/${x_username}
su ${x_username} -c /usr/X11R6/bin/startx 2>/dev/console &
# Засыпаем на 35 секунд, потом снова будем проверять.
# sleep 35
fi
sleep 35
done
#-k en-us
exit;
После чего не забываем сделать их исполняемыми и заводим нужного
юзера:
Ну, можно завести себя, чтоб ходить по ssh, можно разрешить вход
руту. Кому как удобней - тут о секурности можно не особо
беспокоится... Также кладём конфиг для иксов -
/usr/local/etc/thin_configs/conf/xorg.conf.template
# Этот файл не написан мною с нуля, откуда-то скатан рабочий образец и
# рашпилем (это такой напильник с крупными зубьями :)) подрихтован под
# свои нужды. Соответственно комменты - минимальны, и тока в тех местах,
# где вместо фиксированных настроек прописаны переменные.
# Создаём конфиг иксов в /etc/X11/xorg.conf (не забываем, что эта директория
# у меня является симлинком на ``/var/etc/X11'', т.к. ``/'' подмонтирован в
# режиме только чтения.)
echo "# Конфиг тонкого клиента ${win_user_name}. Создан автоматически из
# шаблона ``/usr/local/etc/thin_configs/xorg.conf.template''
# ${current_date} в ${current_time}
Section "Module"
Load "dbe"
SubSection "extmod"
Option "omit xfree86-dga"
EndSubSection
Load "type1"
Load "freetype"
EndSection
" >/etc/X11/XF86Config
# в xorg конфиг называется иначе
#> /etc/X11/xorg.conf
Выкладываем дефолтовый конфиг клиента -
/usr/local/etc/thin_configs/defaults.conf, который сразу можно
подравить под себя (имя домена и сервера)
# first.config
# Имя пользователя - используется для имени хоста,
# и для имени, с которым коннектится
win_user_name="change_user_name_in_config"
# Домен в которых будет логиниться юзер
win_domain="CHANGE-DOMAIN-NAME-IN-CONFIG"
# Имя сервера терминалов
win_ts_server="TS"
# Настройки иксов.
# Горизонтальная развёртка
x_horiz_sync="30-70"
# Частота обновления кадров
x_vert_refresh="60-100"
# Драйвер видеокарты
x_vga_driver="vesa"
# Скольки битный цвет
x_color_bits="24"
# Разрешение моника (именно в одинарных и двойных кавычках!!)
x_resolution='"1024x768"'
Пожалуй, всё. Перезагружаемся, смотрим - подымутся ли иксы. Должны
подняться. Типичный конфиг клиента выглядит так:
/usr/home/lissyara/>more /usr/local/etc/thin_configs/0050BF694851.conf
# Имя пользователя - используется для имени хоста,
# и для имени, с которым коннектится
win_user_name="lissyara"
# Домен в которых будет логиниться юзер
win_domain="DOMAIN.NAME.OF.MY.DOMAIN"
# Имя сервера терминалов
win_ts_server="TerminalServerName"
# Настройки иксов.
# Горизонтальная развёртка
x_horiz_sync="30-70"
# Частота обновления кадров
x_vert_refresh="85"
# Драйвер видеокарты
x_vga_driver="s3virge"
# Скольки битный цвет
x_color_bits="24"
# Разрешение моника (именно в одинарных и двойных кавычках!!)
x_resolution='"1024x768"'
Замечу, что драйвер vesa - практически универсальный, но не всегда
он тянет большое разрешение и частоту обновления, он - выход на
крайний случай, когда не удалось подобрать драйвер производителя.
Осталось последнее - у меня больше половины клиентов, без сетевух с
поддержкой PXE - надо создать загрузочную дискету. Для этого выполняем
такой набор телодвижений (без комментов, тока примечание - делалось на
FreeBSD4.11 на 6.1 будет отличаться.)
P.S. C дискеты довольно долго грузиться, ядро всё же не
маленькое...
P.S.2 Писалось после сделанного, мог чего-то забыть...
P.S.3 Не забываем сделать корень "ro"!