FreeBSD Diskless

от ILuxWiki

Направо към: навигация, търсене


Съдържание

Въведение

Почти всички нови дъна с вградена мрежова карта вече имат възможност да стартират операционната система през мрежата. Това е така наречения network boot. Тук ще се помъча да опиша последнователноста за това как може да се направи с FreeBDS.

Подготовка

За да си направим Network boot разбира се са необходими най-малко 2 машини(разбира се може да се направи тестово изпълнение и с някой виртуална машина: qemu, vmware, parallels...). Задължителното условие е машината която ще изпълнява ролята на клиент да има възможност за мрежово стартиране /проверете BIOS дали има такава опция/.

Необходимия софтуер, в последователност на използване в процеса на стартиране на клиентската машина:

  • dhcp сървър - осигурява IP адреса на клиента според MAC адреса на мрежовата карта.
  • tftp сървър - предоставя файловете поискани от клиента (боот програма, кернел)
  • nfs сървър - осигурява /root файловета система, след зареждане на кърнъла.

Инсталация и настройка на сървъра

Инсталация на операционната система

За текущата инсталация използвам FreeBSD v6.2RC, като след инсталацията синхронизирах sources и ports до последната текуща версия.

Опресняване на sources

Инсталирам cvsup без графична среда

 pkg_add -r cvsup-without-gui

Създавам cvsup.cfg файл и стартирам cvsup

 #cat /etc/cvsup.cfg
 *default host=cvsup9.FreeBSD.org
 *default base=/var/db
 *default prefix=/usr
 *default release=cvs tag=RELENG_6
 *default delete use-rel-suffix
 *default compress
 src-all
 # cvsup -L2 /etc/cvsup.cfg
Прекомпилиране на системата

Това го правя с цел да имам сложени последни поправки, напоследък съм малко разочарован от стабилноста на FREEBSD почти във всички RELEASES имат издънки, чак към P7 или P8 успяват да оправят бозите... Разбира се грешка е да се използва 6.2RC за production сървър - затова ако смятате да правите нещо сериозно препоръчвам да се използва последната стабилна версия на FreeBSD 5.x.

 cd /usr/src
 make buildworld
 make buildkernel
 make installkernel # ако имате специален кърнъл: make installkernel KERNCONF=filename 
 reboot
 mergemaster -p
 make installworld
 make delete-old
 mergemaster
 reboot
 make delete-old-libs # само ако нямате други програми, които ги ползват, но за сега залагаме, че нямате инсталиране допълнителен софтуер

Опресняване на ports

 # portsnap fetch extract


Инсталация и настройка на DHCP сървъра

След като pxe боот частта се стартира на клиента, започва да търси DHCP сървър от който да получи информация IP адреса си и tftpd сървъра от който ще се вземе съответния кърнъл.

 cd /usr/ports/net/isc-dhcp3-server
 make install clean
 echo 'dhcpd_enable="YES"' >> /etc/rc.conf
 

Конфигурационен файл /usr/local/etc/dhcpd.conf :

   authoritative; # server is authoritative for subnets.
   ddns-update-style none;
   use-host-decl-names on;  # send the client the 'hostname', specified in option
   ignore client-updates;
   deny unknown-clients;
   
   option ip-forwarding    false;  # no ip forwarding
   option mask-supplier    false;  # don't respond to icmp masq req
   option domain-name "interbild.net";
   option domain-name-servers 192.168.0.1, 192.168.0.2;
   
   next-server 192.168.100.254;
   filename "pxeboot";
   option root-path "192.168.100.254:/usr/local/diskless";
   
   default-lease-time 43200; # 12 hours
   max-lease-time 86400; # 24 hours
   subnet 192.168.100.0 netmask 255.255.255.0 {
       option routers 192.168.100.254;
       use-host-decl-names on;
   }
   host diskless {
      option host-name "diskless";
      hardware ethernet 00:19:D1:0E:15:FB;
      fixed-address 192.168.100.1;
   }

Инсталация и настройка на tftpd

tftpd използва inetd, ако не сте го пуснали по време на инсталация сега е време да го направим:

 # echo 'inetd_enable="YES"' >> /etc/rc.conf

отворете /etc/inetd.conf и разкоментирайте реда с tftpd

 # killall -HUP inetd || /etc/rc.d/inetd start
 # sockstat -4l | grep 69
 root     inetd      95700 7  udp4   *:69                  *:*

Последната команда ни показва дали inetd е разбрало за промените.

Създаваме pxeboot файла който ще се подава на клиента чрез съвместната работа на DHCP и tfptd.

 # echo "LOADER_TFTP_SUPPORT=YES" >> /etc/make.conf
 # cd /usr/src/sys/boot/i386/
 # make clean; make; make install
 # mkdir /tftpboot  
 # cp /boot/pxeboot /tftpboot

Инсталация и настройка на NFS сървър

След като клиента успешно свали pxeboot файла, в зависимост от root-path настройката в dhcp, той се опитва да се свърже с NFS 192.168.100.254:/usr/local/diskless

Добавете следните редове в /etc/rc.conf:

   rpcbind_enable="YES"
   nfs_server_enable="YES"
   nfs_server_flags="-u -t -n 4 -h 192.168.100.254" # listen only on specific IP

Създаване на файловата система

  • cat diskless.sh
#!/bin/sh
export DESTDIR=/usr/local/diskless
cd /usr/src
make world
make kernel KERNCONF=DISKLESS
cd etc
make distribution
mkdir  $DESTDIR/boot
cp /boot/device.hints $DESTDIR/boot

прекомпилиране на кернела

make buildkernel KERNCONF=DISKLESS
make installkernel KERNCONF=DISKLESS KODIR=/tmp/diskless
mv /tmp/diskless /usr/local/diskless/boot/

Директория /conf

Скриптът /etc/rc.d/rc.initdiskless има възможност да зарежда специфична файлова структура в зависимост от ип-то на машината която използа diskless boot. Специфичната структура се пази в /conf директория. В нашия случай това е $DESTDIR/conf.

Структура

Структурата на /conf е следната /conf/T/M, където:

  • M - имена на директорий които ще бъдат създадени в виртуалната файлова система(в паметта)
  • T - TEMPLATE директорий описани тук:
    • base - основната база, обикновенно копие на оригиналния root дял;
    • default - вторична база, обикновенно презастъпва някой файлов от оригиналиния root дял;
    • ${ipba} - където ${ipba} е broadcast IP адреса;
    • bcast/${ipba} - същото като предното;
    • ${class} - където ${class} е списък от директории предоставени от bootp/dhcp чрез Т134 параметър. Обикновенно ${ipba} и ${class} се използва за конфигурации от група клиенти с еднакви настройки, понякога и за специфични такива. За да го използвате добавете option unknown-134 "router"; в dhcpd.conf
    • ${ip} - където ${ip} е IP адреса на машината която боотва;
    • ip/${ip} - същото като предното;

Шаблонните директории се обхождат по реда описан преди малко, като всяка следваща се презастъпва предходната; несъществуващите дикектории се игнорират.

Някой файлове в /conf имат специално значение:

  • /conf/T/M/remount - съдържанието на този файл е mount команда. Примерно, ако /conf/1.2.3.4/foo/remount съдържа mount -o ro /dev/ad0s3, тогава /dev/ad0s3 ще бъде монтирана в /conf/1.2.3.4/foo/;
  • /conf/T/M/diskless_remount - Съдържанието на този файл е насочено към NFS файловата система. Примерно, ако /conf/base/etc/diskless_remount съдържа foo.com:/etc, тогава foo.com:/etc ще бъде монтирана /conf/base/etc/. Ако файлът съдържа име на път с "/", тогава root дяла ще го използва; това дава възможност за преместаване на root файловата система без смяна на конфигурационните файлове.
  • /conf/T/M/md_size - съдържанието на този файл определя големината на виртуаната файлова система, която ще бъде създадена в паметта, в блокове от 512 байта. Стандартната големина е 10240 блока(5 мегабайта). За пример ако /conf/base/etc/md_size съдържа 30000 тогава ще бъде създадена 15 мегабайтова MFS. В случай на повече директиви, в същата М директория, се взема в предвид само последната според реда на сканиране. ЗАБЕЛЕЖКА: Ако се нуждаете от файлова система в паметта, но не искате да се създава от шаблона, препоръчително е да използвате fstab, като въведете информацията по следния начин: md /tmp mfs -s=30m,rw 0 0
  • /conf/T/SUBDIR.cpio.gz - този файл е cpio архив на /SUBDIR и ще бъде разархивиран в тази директория (/SUBDIR ще бъде създадена при необходимост). Съществуването на този файл, блокира копирането на /subdir.
  • /conf/T/SUBDIR.remove - Върху списъкът на пътища в този файл ще бъде приложена командата rm -rf, в папка /SUBDIR.

Почти винаги е необходимо да създадете следните файлове в /conf: файл - съдържание

/conf/base/etc/md_size големината на /etc файловата система

/conf/base/etc/diskless_remount "/etc"

/conf/default/etc/rc.conf основни diskless настройки

/conf/defailt/etc/fstab базон diskless fstab

Примерно съдържание:

 foo:/root_part          /       nfs     ro              0 0
 foo:/usr_part           /usr    nfs     ro              0 0
 foo:/home_part          /home   nfs     rw              0 0
 md                      /tmp    mfs     -s=30m,rw       0 0
 md                      /var    mfs     -s=30m,rw       0 0
 proc                    /proc   procfs  rw              0 0

Да не забравите също и да подмените passwdфайловете.

ЗАБЕЛЕЖКА: /var, /tmp и /dev обикновенно се създават на друго място, примерно в fstab. тези файлови системи не трябва да се описват в /conf.

(този текст е частичен превод от /etc/rc.d/rc.initdiskless)

Допълнителни директории и файлове

 mkdir /usr/local/diskless/home    # използва се за монтиране на home dirs
 mkdir /usr/local/diskless/g00net  # разни скриптове стоят тук

Директория: /usr/local/diskless/conf/default/etc

файл: fstab

 # vim: synt off 
 10.254.0.254:/usr/local/diskless /              nfs     ro      0 0
 10.254.0.254:/nfs_home           /usr/home      nfs     rw      0 0
 10.254.0.254:/usr/ports/packages /packages      nfs     ro      0 0
 md      /usr/local/etc  mfs     -s=1m,rw        0 0
 #md     /var            mfs     -s=15m,rw       0 0

файл: rc.conf

 nisdomainname="ib-mdf"
 nis_client_enable="YES"
 sshd_enable="YES"

файл: passwd

Ако се използва NIS се добавя следния ред най-отдоле

 +:*:::::

файл: master.passwd

Да се създаде само ако се ползва NIS, същия като base, без потребителски акаунти NIS на последния ред:

 +:::::::::
  • Трябва да се създадат и съответните hash файлове

файл: group

За NIS на последния ред се добавя:

 +:*::

файл: rc.local

TODO

Пакети

Команди

Създаване на директория в която ще се пазят компилираните пакети:

    mkdir /usr/ports/packages

Инсталиране на пакети:

   portinstall -rp <packetname>

Опресняване на пакетите:

   portupgrade -rp <packetname>

Списък на инсталираните пакети

   ADMsmb-0.3          Security scanner for Samba
   arpwatch-2.1.a15_4  Monitor arp & rarp requests
   autoconf-2.59_2     Automatically configure source code on many Un*x platforms 
   automake-1.9.6      GNU Standards-compliant Makefile generator (1.9)
   bubblegum-1.12      Watch a file for changes
   cpuburn-1.4         CPU/memory stress testing utilities
   cvsup-without-gui-16.1h_2 General network file distribution system optimized for CVS 
   db41-4.1.25_4       The Berkeley DB package, revision 4.1
   ezm3-1.2_1          Easier, more portable Modula-3 distribution for building CV
   fping-2.4b2         Quickly ping N hosts w/o flooding the network
   gawk-3.1.1_1        The GNU version of Awk
   gettext-0.14.5_2    GNU gettext package
   gmake-3.81_1        GNU version of 'make' utility
   help2man-1.36.4_1   Automatically generating simple manual pages from program o
   isc-dhcp3-server-3.0.5 The ISC Dynamic Host Configuration Protocol server
   libiconv-1.9.2_2    A character set conversion library
   libtool-1.5.22_2    Generic shared library support script
   m4-1.4.8_1          GNU m4
   mc-light-4.1.40.p9_6 A lightweight Midnight Commander clone
   mime-support-3.39.1 MIME Media Types list
   mprime-0.0.24.14    mersenne.org distributed Great Internet Mersenne Prime Sear
   mtr-nox11-0.72      Traceroute and ping in a single graphical network diagnosti
   munin-node-1.2.5    Node-specific part of Munin
   mutt-lite-1.4.2.2   mutt, the Mongrel of Mail User Agents (lite package)
   mysql-client-4.1.22 Multithreaded SQL database (client)
   ngrep-1.45          Network grep
   nmap-4.20           Port scanning utility for large networks
   p5-Authen-PAM-0.16_1 A Perl interface to the PAM library
   p5-DBD-mysql41-4.0000 MySQL 4.1 driver for the Perl5 Database Interface (DBI)
   p5-DBI-1.53         The perl5 Database Interface.  Required for DBD::* modules
   p5-IO-Multiplex-1.08 IO::Multiplex - Manage IO on many file handles
   p5-Net-SSLeay-1.30_1 Perl5 interface to SSL
   p5-Net-Server-0.94  A configurable base class for writing internet servers in P
   p5-Storable-2.15    Persistency for perl data structures
   p5-gettext-1.05_1   Message handling functions
   pcre-7.0            Perl Compatible Regular Expressions library
   perl-5.8.8          Practical Extraction and Report Language
   pkg-config-0.21     A utility to retrieve information about installed libraries
   portaudit-0.5.11    Checks installed ports against a list of security vulnerabi
   portupgrade-2.2.2_1,2 FreeBSD ports/packages administration and management tool s
   quagga-0.99.6       Free RIPv1, RIPv2, OSPFv2, BGP4, IS-IS route software
   ruby-1.8.5.12,1     An object-oriented interpreted scripting language
   ruby18-bdb-0.5.9_2  Ruby interface to Sleepycat's Berkeley DB revision 2 or lat
   screen-4.0.3        A multi-screen window manager
   smartmontools-5.37  S.M.A.R.T. disk monitoring tools
   trafshow-3.1_5,1    Full screen visualization of network traffic (an ancient ve
   vim-lite-7.0.178_3  Vi "workalike", with many additional features (Lite package
   webmin-1.310_2      Web-based interface for system administration for Unix

Особености

  • quagga:
  mkdir conf/default/var/run/quagga
  chown quagga:quagga conf/default/var/run/quagga
  • munin:

В конфигурационния файл се задава откъде да има достъп (fetch), както и една поправка за freebsd - губи се пътя $PATH когато се вика munin, затова трябва да се добави това в конфигурацията:

  allow ^127\.0\.0\.1$
  [mysql*]
  user root
  group wheel
  env.mysqladmin /usr/bin/mysqladmin
  env.mysqlopts –defaults-extra-file=/root/.my.cnf

Скриптове

Опреснява дб-то след добавяне на пакет изискващ промяна на master.passwd

   pwd_mkdb -d`pwd` ./master.passwd
   ~/diskless# diff -qr var /diskless_conf/default/var

/root/bin/diskless_cpio

  #!/bin/sh
 
 config_dir='/diskless_conf'
 cpio_target_ip()
 {
     target=$1
     ip=$2
     dirname=$3
     check_target $target
     pw_dir="${config_dir}/${target}/${ip}/${dirname}"
     if [ -d "${pw_dir}" ]; then
         cd "${config_dir}/${target}/${ip}"
         echo "Creating ${dirname}.cpio.gz "
         tar zcfv ${dirname}.cpio.gz ${dirname}
         echo "."
         
     else 
         echo "invalid directory: $pw_dir"
         exit 1
     fi
 }
 
 not_impl()
 {
     echo "Not implemented"
     exit 1;
 }
 check_target()
 {
     case $1 in
     base)
         echo "base"
         ;;
     ip)
         echo "ip"
         ;;
     *)
         echo "Error: Invalid target: $1"
         exit 1
     ;;
     esac
 }
 case $# in
 1)
     dirname=$1
     if [ -d $dirname ]; then
         echo "Creating ${dirname}.cpio.gz "
         tar zcfv ${dirname}.cpio.gz ${dirname}
         echo -n "."
     else
         echo "Usage: $0 <dirname>"
         exit 1
     fi
     ;;
 2)
     # base
     if [ $1 -gt 0 ]; then
         cpio_target_ip ip $1 $2
     else
         not_impl
     fi
     ;;
 3)
     cpio_target_ip $@
     ;;
 *)
     echo "Usage"
     ;;
 esac
 
 exit;
 dirname=$1
 if [ -d $dirname ]; then
         echo "Creating ${dirname}.cpio.gz "
         tar zcfv ${dirname}.cpio.gz ${dirname}
         echo -n "."
 else
         echo "Usage: $0 <dirname>"
         exit 1
 fi

/root/bin/diskless_newuser

 #!/bin/sh
 if [ ! -s $1 ]; then
         pw useradd $1 -h0 -s /bin/tcsh -V /var/yp -Y $@
 else 
         echo "Usage: $0 <username> [pw args]"
         exit 1
 fi

/root/bin/diskless_cpboot

   #!/bin/sh
   
   src='/boot'
   dest='/usr/local/diskless/boot'
   
   # create some directories
   if [ ! -d "$dest/defaults" ]; then
   	mkdir -vp "$dest/defaults"
   fi
   for file in beastie.4th frames.4th loader loader.4th loader.rc \
   	loader.help defaults/loader.conf; do
   	if [ ! -f "$dest/$file" ]; then
   		cp -v "$src/$file" "$dest/$file"
   	else
   		echo "$src/$file" already exists
   		diff "$src/$file" "$dest/$file" | more
   	fi
   done

TODO

  1. Скрипт който сам да сглобява:
    1. zebra.conf
    2. bgpd.conf
    3. ipfw.conf
  2. Попълване на /usr/local/etc/

Документация