понедельник, 4 апреля 2011 г.

О терминальном решении


Говорят,  что история развивается по спирали. Другие же утверждают что
   она  вовсе  движется  по кругу. Так или иначе, но история терминальных
   решений  довольна  любопытна  -- IT технологии, казалось, окончательно
   ушли от меинфреймов в сторону персональных
   компьютеров в начале девяностых, но вот теперь опять возвращаются к ним.
   Через 15 лет.

   Терминальные решения имеют множество недостатков перед архитектурой ПК.
   Это и меньшая гибкость,   и   жесткая  зависимость  от  центрального
   сервера,   повышенные   требования   к  надежности  сети,  обязательна
   необходимость  дублирования  основных  сервисов.  Но в тоже время, они
   обеспечивают   повышенную  безопасность,  простоту  администрирования,
   высокий  уровень  контроля  системы.  А  в  ряде  случаев  позволяют и
   существенно экономить на ПО.

   Рассматриваемое  решение  комбинирует  использование  проприетарного и
   открытого  программного  обеспечения.  Использование  linux в качестве
   терминальных  клиентов позволяет существенно сэкономить на программном
   обеспечении  и  повысить надежность решения. Ни для кого не секрет что
   решения  на  базе unix являются более надежными чем на базе windows. В
   тоже  время,  использование  в качестве серверной операционной системы
   Windows   2003   TS  избавляет  нас  от  сложностей  с  совместимостью
   программного  обеспечения,  обучением  пользователей  и  пр.  --  ваши
   пользователи  работают в родной для них среде, даже не догадываясь что
   на их терминальных машинах запущен линукс.

   Краткая схема используемого решения

   Решение основывается на трех составляющих:
     * Терминальный сервер с Windows 2003 Terminal Server
     * Linux  сервер на котором запущены dhcp, tftp, nfs и хранится образ
       системы ltsp
     * Бездисковые терминальны станции с возможностью загрузки по сети

   Я не буду подробно останавливаться на особенностях настройки Windows 2003 Terminal Server.
   По  данной  тематике  написано  немало  статей, да и сама настройка
   довольно   тривиальна.   Рекомендую   лишь   внимательно  отнестись  к
   аппаратному   обеспечению   --  хот-свап  блоки  питания,  оперативная
   память с ECC  выбирается  из  расчета  -- не меньше 512 Мб оперативной
   памяти  под систему и 64 Мб оперативной памяти на каждого пользователя
   обслуживаемого  сервером,  raid  массивы  с  быстрыми  дисками.  Также
   обращаю  ваше  внимание  на  особенности  лицензирования  программного
   обеспечения  Майкрософт -- версия Windows 2003 server standart edition
   допускает использование от 1-4 процессоров и не более 4 Гб оперативной
   памяти.   Версия  Enterprise Edition поддерживает до 64 Гб в 32-битной
   версии, и до 2 Тб в 64х.

   Линукс-часть  состоит  из  линукс  сервера, на котором запущены демоны
   dhcp,  nfs,  tftp  и  хранится  загружаемый  терминалом образ линукса.
   Впринципе,  его  можно  создать  и  самостоятельно, но гораздо удобнее
   использовать готовую систему -- [9]Linux Terminal Server Project .

   Терминальный клиент загружается по сети: получает по dhcp ip адрес, за
   гружает по tftp ядро линукс, монтирует по nfs  образ корневой файловой
   системы, загружает ramdisk, запускает графическую подсистему xwindow и
   стартует    терминальный   клиент   rdesktop,   с   помощью   которого
   подсоединяется к windows 2003 terminal server.
   Настройка Linux сервера

I. DHCP

   Для  загрузки ваших клиентских станций по сети необходимо наличие DHCP
   сервера.  DHCP  сервер  выделяет  ip  адреса  для терминалов, передает
   параметры  загрузки  и  сообщает путь к образу ядра ОС. Рекомендуется,
   чтобы этим dhcp сервером был сервер linux или unix. В вашей сети могут
   существовать  другие  DHCP  сервера,  например  от  adsl  роутера  или
   какого-либо   сетевого   устройства.  Чтобы  исключить  конфликт  DHCP
   серверов,  рекомендую  оставить один главный DHCP сервер. Однако, если
   это   невозможно,  то  предется  цеплять  ваш  новый  DHCP  сервер  на
   альтернативный   порт,   например   1067  и  передавать  загрузчику  в
   параметрах  ядра  новый  порт. В такой схеме раздачей ip адресов будет
   заниматься один DHCP сервер, а передачей ядра и параметров загрузки --
   другой.  Эта  схема  возможна,  но  неудобна,  так  что в общем случае
   рекомендую оставить один DHCP сервер.

   Инсталируем      DHCP      сервер.      Скачиваем      исходники     с
   http://www.isc.org/index.pl?/sw/dhcp/   ,  конфигурируем,  собираем  и
   ставим.

   Переходим к файлу конфигурации, /etc/dhcp/dhcpd.conf

             # Глобальные настройки
             not authoritative;
             default-lease-time 28800; # 8 часов
             max-lease-time 86400; # 1 день
             use-host-decl-names on; # Задавать hostname клиента
             ddns-update-style none; # Сособ обновления динамического DNS

             # Сетевые настройки
             option subnet-mask 255.255.255.0;
             option broadcast-address 192.168.0.255;
             option routers 192.168.0.99; # Шлюз по умолчанию
             option domain-name-servers 192.168.0.99; # Наш сервер
             option log-servers 192.168.0.99; # Сервер remote logging
             option nntp-server 192.168.0.99; # time server
             next-server 192.168.1.2; # TFTP сервер

             # Настройки загрузки
             boot-unknown-clients   false;   #   Запретить  загрузку  неизвстных клиентов
             allow booting;
             allow bootp;

             # Настройки PXE
             option option-128 code 128 = string;
             option option-129 code 129 = text;
             option option-128 e4:45:74:68:00:00; # magic value

             # Describe workstations
             shared-network LTSPCLIENTS {
             option  domain-name  "ltsp.works.kamrock.com"; # Имитация доменного имени для ltsp клиентов
             option  root-path  "192.168.0.99:/opt/ltsp-4.2/i386''; # NFS путь к корню образа ltsp клиента

             if substring (option vendor-class-identifier, 0, 9) = "PXEClient" {
                 filename "/pxe/pxelinux.0''; # PXE bootrom
             }
             else   if   substring  (option  vendor-class-identifier,  0,  9)  =   "Etherboot" {
                 filename "/lts/vmlinuz-2.6.17.8-ltsp-1''; # Etherboot kernel
             }

             subnet 192.168.0.0 netmask 255.255.255.0 {
             # Диапазон IP адресов для DHCP
             range 192.168.0.30 192.168.0.90;

             group DESKTOP {
                 host ws001 {
                     hardware ethernet 00:0C:29:72:48:44;
                     fixed-address 192.168.0.30;
                 }
                 host ws002 {
                     hardware ethernet 00:15:F2:60:18:67;
                     fixed-address 192.168.0.31;
                 }
                 host ws003 {
                     hardware ethernet 00:17:31:4B:35:45;
                     fixed-address 192.168.0.32;
                     }
             }
             # group LIBRARY {
             # # Пример для альтернативного DHCP порта 1067 (Etherboot)
             # host ws100 {
             # hardware ethernet 00:C0:4F:AD:5C:BC;
             # fixed-address 10.0.0.100;
             # option option-129 "DPORT=1067'';
             # }
             # # support for DHCP port 1067 & slow 3Com ISA NIC
             # host ws101 {
             # hardware ethernet 00:60:08:5C:CB:BE;
             # fixed-address 10.0.0.101;
             # option option-129 "DPORT=1067 NIC=3c509 MOPTS=nolock,ro,wsize=2048,rsize=2048'';
             # }
             # another client with a slow ISA NIC
             # host ws102 {
             # hardware ethernet 00:C0:4F:AD:5D:55;
             # fixed-address 10.0.0.102;
             # group LAB {
             # # trick to use, when there are two conflicting DHCP servers
             # # and the dumb one is authoritative
             # host ws103 {
             # hardware ethernet 00:C0:4F:AD:5D:55;
             # fixed-address 10.0.0.103;
             # option option-129 "nfsroot=10.0.0.11:/opt/ltsp/i386'';
             #
             # }
             # }
             }
             }


   Запускаем dhcp

             /etc/init.d/dhcpd start


   и  проверяем  его  работу  --  запускаем  загрузку прописанного в dhcp
   клиента по сети.

   При этом мы должны получить примерно такую картину:

             Network boot from AMD Am79C970A
             Copyright (c) 2003-2005 VMware, Inc.
             Copyright (c) 1997-2000 Intel Corporation

             CLIENT MAC ADDR: 00 0C 29 72 48 44 GUID:
             564D4E8E4-08DF-DAC3-A4C3-BDF5F9724844
             CLIENT IP: 192.168.0.30 MASK: 255.255.255.0 DHCP IP: 192.168.0.99
             GATEWAY IP: 192.168.0.99
             PXE-E32: TFTP open timeout


   Она  зависит  от  типа используемого адаптера, но смысл один -- клиент
   получает  от  DHCP  сревера  IP  адрес  и производит неудачную попытку
   загрузить  ядро  по  TFTP.  Это  означает  что  DHCP сервер настроен и
   работает.


II. TFTP

   При  загрузке  ltsp  клиент  получает  образ  ядра от сервер с помощью
   протокола  tftp.  Соответственно,  необходимо  установить  некий  tftp
   сервер.  Существует  несколько  реализаций  tftp  серверов под unix. Я
   остановился на [10]tftp-hpa. Есть еще [11]atftp, по сути тоже самое.
   У  tftp-hpa есть один неприятный баг. По крайней мере в использованной
   версии 0.48 и более ранних. При наличии нескольких сетевых интерфейсах
   он намертво цепляется к первому, несмотря на опции запуска

             -u nobody -s -a 192.168.0.99:69 /tftpboot


   которые  должны  цепляеть  его  к интерфейсу с ip 192.168.0.99. Причем
   цепляется  таким  образом, что принимает соединение и на 192.168.0.99,
   т.е.  на тот интерфейс на который забинден, но отправлять пакеты хочет
   ТОЛЬКО   от  первого  интерфейса,  т.е.  192.168.1.2  в  моем  случае.
   Чувствуете  разницу? Фактически по телнету ошибки не будет, но ядро не
   перешлется )
   
   Имейте  это  в  виду  -- баг не фатальный, можно использовать и второй
   интерфейс  для раздачи tftp, но крови попьет он массу -- клиент просто
   не будет загружаться, несмотря ни на что.
   Так что биндим сразу при запуске tftp на первый интерфейс

             -u nobody -s -a 192.168.1.2:69 /tftpboot


   и в настройках DHCP в директиве

             next-server 192.168.1.2; # TFTP сервер


   прописать ip адрес первого сетевого адаптера для TFTP сервера.

   Кроме  того, необходимо открыть порт 69 udp на вашем фаерволе, если он
   у вас есть:

             #!/bin/sh
             IPTABLES = /sbin/iptables

             $IPTABLES  -A  INPUT -p udp -m state -state NEW -m udp -dport 69 -j ACCEPT
             $IPTABLES  -A OUTPUT -p udp -m state -state NEW -m udp -dport 69 -j ACCEPT


   Все готово, запускаем tftp:

                /etc/init.d/in.tftpd start


   И заново пробуем загрузить ltsp клиента:

             Network boot from AMD Am79C970A
             Copyright (c) 2003-2005 VMware, Inc.
             Copyright (c) 1997-2000 Intel Corporation

             CLIENT MAC ADDR: 00 0C 29 72 48 44 GUID:
             564D4E8E4-08DF-DAC3-A4C3-BDF5F9724844
             CLIENT IP: 192.168.0.30 MASK: 255.255.255.0 DHCP IP: 192.168.0.99
             GATEWAY IP: 192.168.0.99
             PXELINUX 2.13 2004-12-14 Copyright (C) 1994-2004 H. Peter Anvin
             UNDI data segment at: 0009C7F0
             ...
             Could not find kernel image: bzImage-2.6.17.8-ltsp-1
             boot:


   Делаем  вывод  -- DHCP работает, TFTP работает. Приступаем к настройке
   ltsp.


III. LTSP

   Метод инсталяции LTSP примечателен -- идем на [12]ltsp.org и утягиваем
   пакет ltsp-utils.
   Запускаем ltspadmin, выбираем "Install/Update LTSP Packages", выделяем
   все объекты и нажимаем "Q". Инсталятор скачивает нужные пакеты из сети
   и копирует их в /opt/ltsp-версия.

   После  инсталяции  скрипт  возвращает  нас  в  основное меню. Выбираем
   "Configure  LTSP".  Если  при  этом  вываливаются  какие-либо ошибки в
   тесте, игнорируем их.
   Дальше выполняем:

             # [c]
             # [8]
             # [enter]
             # [10]
             # [enter]
             # [11]
             # [enter]
             # [q]
             mkdir /tmp/{mnt,var}
             cd /opt/
             ln -s ltsp-${VER} ltsp
             cd /tftpboot/
             mv pxelinux.cfg/ pxe/
             ln -s pxe/pxelinux.cfg pxelinux.cfg


   и выходим из скрипта инсталятора.

   Переходим  к  настройке  LTSP.  Основным  файлом  с  настройками  LTSP
   является /opt/ltsp/i386/etc/ltsp.conf:

             #  LTSP  Configuration  Parameter  Reference last modified: May 14, 2005
             #
             # The lts.conf file is made of "sections". That is, there can be a
             # default section called `[default]'. There can also be sections
             #   for  each  individual  workstation.  Entries  in  the  specific workstation
             # sections take precedence over entries in the default section.
             #  The workstation can be identified by hostname, IP address or MAC address.
             # That is, if ws004 has an IP address of 192.168.0.4 and a MAC
             #  address  of 00:50:56:59:7F:81, it can be specified by any of the following:
             #

             #-----------------------------------------
             # It test
             #-----------------------------------------
             [ws001]
             SCREEN_01 = rdesktop -k ru -f 192.168.0.97
             SERVER = 192.168.0.99
             XSERVER=auto
             X_MODE_0 = 1024 *768
             X_MOUSE_PROTOCOL="PS/2''
             X_MOUSE_DEVICE="/dev/psaux"
             X_MOUSE_RESOLUTION=200
             X_MOUSE_BUTTONS=3
             X_COLOR_DEPTH=16

             #-----------------------------------------
             # IT Dima
             #-----------------------------------------
             [ws002]
             SCREEN_01 = rdesktop -k ru -f 192.168.0.97
             SERVER = 192.168.0.99
             XSERVER = auto
             PRINTER_0_DEVICE = /dev/usb/lp0
             PRINTER_0_TYPE = U
             XF86CONFIG_FILE = X86Config.Samsung710N
             X_MOUSE_PROTOCOL = "ImPS/2''
             X_MOUSE_DEVICE = "/dev/input/mice"
             X_MOUSE_RESOLUTION=200
             X_MOUSE_BUTTONS=3
             X_COLOR_DEPTH=16


   Все   прозрачно.  Секции  начинаются  с  имени  конфигурируемого  ltsp
   клиента.
   
   Первая  строка  -- открываемая сессия. Мы запускаем rdesktop, включаем
   русскую  раскладку  клавиатуры  и  соединяемся с терминальным серверов
   192.168.0.97  в  режиме  фулл-скрин.  Дальше  идут  параметры иксов --
   разрешение,  тип  используемой  мыши, разрешение отклика мыши, глубина
   цветности.  Для первого клиента используем мышь PS/2, для второго USB.
   
   Если вы не знаете какой тип мыши на машине клиента -- перечислите оба.
   Кроме того, для второго клиента мы определили что подключаем локальный
   USB   принтер,   а   настройки   исков   прописаны  в  отельном  файле
   X86Config.Samsung710N.  Об этом подробнее немного позже, когда я дойду
   до описания локальных устройств терминального клиента.
   Добавляем нужное число секций по числу клиентов.
   Кроме   этого,   не   забываем   отразить   добавленного   клиента   в
   /etc/dhcp/dhcpd.conf в секции group DESKTOP:

             host ws001 {
                 hardware ethernet 00:0C:29:72:48:44;
                 fixed-address 192.168.0.30;
             }


   А также добавить строчку в /etc/hosts:

             192.168.0.30 ws001.works.kamrock.com ws001


   Проверяем   работу.  Запускаем  нашего  несчастного  ltsp  клиента,  и
   получаем картину сливочным маслом:

             Network boot from AMD Am79C970A
             Copyright (c) 2003-2005 VMware, Inc.
             Copyright (c) 1997-2000 Intel Corporation

             CLIENT MAC ADDR: 00 0C 29 72 48 44 GUID:
             564D4E8E4-08DF-DAC3-A4C3-BDF5F9724844
             CLIENT IP: 192.168.0.30 MASK: 255.255.255.0 DHCP IP: 192.168.0.99
             GATEWAY IP: 192.168.0.99
             PXELINUX 2.13 2004-12-14 Copyright (C) 1994-2004 H. Peter Anvin
             UNDI data segment at: 0009C7F0
             ...
             Mounting root filesystem: /opt/ltsp-4.2/i386 from: 192.168.0.99
             mount: RPC: Unable to receive; errno = Connection refused
             mount: nfsmount failed: Bad file descriptor
             mount: Mounting 192.168.0.99:/opt/ltsp-4.2/i386 on /newroot/nfsroot
             failed: Inva
             lid argument
        
             ERROR! Failed to mount the root directory via NFS!
             Possible reasons include:

             1) NFS services may not be running on the server

             2) Workstation IP does not map to a hostname, either
             in /etc/hosts, or in DNS
        
             3) Wrong address for NFS server in the DHCP config file
        
             4) Wrong pathname for root directory in the DHCP config file
        
             Kernel panic -- not syncing: Attempted to kill init!


IV. NFS

   После  загрузки  ядра  ltsp  клиент  пытается  подмонтировать файловую
   систему  с  образом системы клиента. Для этого необходимо установить и
   настроить на сервер NFS.

   Скачиваем   и   настраиваем   nfs-utils.   Подробно   на   этой  части
   останавливаться  не буду, в сети много примеров. Да и никаких багов на
   этом   этапе  замечено  мною  не  было.  Очень  подробная  инструкция:
   http://gentoo-wiki.com/HOWTO_Share_Directories_via_NFS
   После инталяции выполняем следущее:

             mkdir -p /var/opt/ltsp/swapfiles
             vim /etc/exports


   Правим /etc/exports:

             # NFS file systems being exported. See exports(5).
             /opt/ltsp-4.2/i386 192.168.0.99/255.255.255.0(ro,async,subtree_check)
             /var/opt/ltsp/swapfiles 192.168.0.99/255.255.255.0(rw,async,subtree_check)


   Кроме  того,  если  у  вас есть фаервол, вам необходимо произвести ряд
   действий  для  настройки портов по которым работает NFS и открытия их.
   Довольно подробно об этом тут:
   http://gentoo-wiki.com/HOWTO_Share_Directories_via_NFS#Setting_Up_Firewall_.28Server_Side.29

   Запускаем и тестируем:

             /etc/init.d/portmap start
             /etc/init.d/nfs start


   Загружаем  наш ltsp клиент. Если все сделано правильно, то запускается
   линукс,  стартуют  иксы  и  появляется интерфейс логина в windows 2003
   server.  Ну  или  просто  иксы,  если windows 2003 server у вас еще не
   настроен и не запущен )


V. Исправление багов. Ошибка залипающего ALT
   
   LTSP  и RDESKTOP имеют некую особенность. Проявляется она при попытках
   переключения  между  раскладками  с  использованием  ALT  + SHIFT. При
   использовании  такой комбинации возникает эффект залипания LEFT ALT, и
   клавиатура "зависает".
   Исправляется следующим образом:
   в файле  /opt/ltsp/i386/usr/X11R6/lib/X11/xkb/keycodes/xfree86
   комментируем строчку c < lalt > = 64;

             # < lalt > = 64;


   Таким  образом отключаем левый алт в линуксе. Т.к. rdesktop работает с
   windows  2003  terminal server метом передачи кодов нажатых клавиш, то
   на  функциональности клавишы LEFT ALT в windows это сказывается только
   положительно  --  она  перестает  конфликтовать  с такой же клавишей в
   linux  и  при  переключении  раскладок  по LEFT ALT + SHIFT клавиши не
   залипают.


VI. Русификация

   При  запуске  rdesktop  мы используем русскую раскладку клавиатуры для
   rdesktop. Напоминаю строчку из /opt/ltsp/i386/etc/ltsp.conf: 

           SCREEN_01 = rdesktop -k ru -f 192.168.0.97


   К сожаленью, раскладка требует доработки. Я бы сказал -- кординальной.
   При  использовании  дефолтной ru раскладки не работает часть клавиш, в
   частности  не  ставится  точка в русской раскладке (та что совмещена с
   клавишей  "/").  Кроме  того, не работает shift + \ . Т.е. не ставится
   бекслеш. Координальный метод исправления состоит в следующем:
   идем  в  /opt/ltsp/i386/usr/share/rdesktop/keymaps  и  замещаем файл с
   раскладкой ru файлом с раскладкой en-us:

            rm /opt/ltsp/i386/usr/share/rdesktop/keymaps/ru
        cp     /opt/ltsp/i386/usr/share/rdesktop/keymaps/en-us /opt/ltsp/i386/usr/share/rdesktop/keymaps/ru


   После чего заменяем в /opt/ltsp/i386/usr/share/rdesktop/keymaps/ru

             map 0 *409


   на

             map 0 *419


   "Новая" ru раскладка готова. Все клавишы работают корректно.


VII. Локальные устройства. Нестандартные мониторы

   В  ряде  случаев  скрипт  из ltsp, призванный автоопределить параметры
   устройств для запуска xorg, дает сбой. В частности, у меня некорректно
   определялись  параметры  горизонтальной развертки для части мониторов.
   Например,  для  Samsung 710N. Как результат, было невозможно выставить
   родное для данного монитора разрешение.

   Вариант  решения  проблемы следующий -- написать специальный X86Config
   для  данного  монитора.  Т.к.  угадывать параметры устройства самому и
   писать   файл  конфига  довольно  муторно,  то  можно  воспользоваться
   следующим   хитрым   методом.  Скачиваем  дистрибутив  с  [15]Knoppix.
   Загружаемся с CD или DVD с Кнопиксом на проблемной машине с проблемным
   монитором.  В  составе  Knoppix  идет  гениальный скрипт распознования
   параметров устройств, mkxf86config, практически не дающий сбоев. После
   загрузки  копируем  сгенирированный  кнопиксом  X86Config из рам диска
   Кнопикса  к  нам  на  сервер,  в  каталог с ltsp.conf. И задаем данный
   конфиг в параметрах запуска ltsp клиента в ltsp.conf:

             XF86CONFIG_FILE = X86Config.Samsung710N


   После загругзки ltsp получаем нужное родной разрешение монитора.


VIII. Локальные устройства. Принтеры

   LTSP   позволяет   использовать  локальные  принтеры,  подключенные  к
   терминальной   машине   как  по  USB,  так  и  по  LTP.  Для  этого  в
   /etc/ltsp.conf,  в  секции  настройки  клиента,  прописываем  для  USB
   принтера:

             PRINTER_0_DEVICE = /dev/usb/lp0
             PRINTER_0_TYPE = U


   После  загрузки  принтер  работает  и  доступен. При этом, ltsp-клиент
   становится  принт-сервером  и  принтер  становится сетевым, обладая ip
   адресом ltsp клиента. Таким образом, для добавления принтера в windows
   надо произвести стандартную процедуру добавляения сетевого принтера:

     * выбрать добавление нового принтера
     * выбрать "Локальный принтер"
     * "Создать новый порт", тип порта установить в Standart TCP/IP Port
     * ввести ip адрес ltsp клиента


   Вуаля, принтер доступен.

   IX. Локальные устройства. USB флеш носители
   Rdesktop   и   LTSP   позволяют   использовать  в  терминальной  схеме
   подключение локальных USB носителей. Подробную статью об этом процессе
   я описал тут: USB флеш диски в LTSP и Rdesktop

Комментариев нет:

Отправить комментарий