суббота, 27 июня 2009 г.

Какой дистрибутив установлен linux на компьютер

можно узнать с помощью утилиты lsb_release.
Пример использования

$ lsb_release -irc
Distributor ID: Ubuntu
Release: 9.04
Codename: jaunty
Если этой утилиты в исследуемой системе нет, то версию дистрибутивов, основанных на Debian/RedHat/Gentoo можно узнать так (спасибо Ярославу Шаповалу)
$ cat /etc/*release*
в дистрибутивах, основанных на Slackware
$ cat /etc/slackware-version
в SUSE
$ cat /etc/issue

суббота, 13 июня 2009 г.

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

Дополнительная настройка DHCP-клиента может понадобится когда у вас есть локальный DNS-сервер или если DHCP-сервер провайдера работает с перебоями.

Пример файла конфигурации «/etc/dhcp3/dhclient.conf»

  1. #
  2. # dhcp3-client 3.1.1-5ubuntu8
  3. #
  4. # Сюда вписываем локальный адрес DNS-сервера
  5. prepend domain-name-servers 127.0.0.1;
  6. # Какие данные нужно затребовать с DHCP-сервера
  7. request subnet-mask, broadcast-address, time-offset, routers,
  8. # Комментируем, так как у нас локальный DNS-сервер
  9. # domain-name, domain-name-servers, domain-search, host-name,
  10. netbios-name-servers, netbios-scope, interface-mtu,
  11. rfc3442-classless-static-routes, ntp-servers;
  12. #
  13. # dhclient будет использовать эти настройки, в то время,
  14. # когда недоступен DHCP-сервер провайдера.
  15. #
  16. # Если не знаете что писать - загляните в файл
  17. # /var/lib/dhcp3/dhclient.leases
  18. #
  19. lease {
  20. interface "eth1";
  21. fixed-address 72.xxx.xxx.xxx;
  22. option subnet-mask 255.255.xxx.xxx;
  23. option time-offset 32400;
  24. # Если прописать адреса роутеров, dhclient проверит наличие
  25. # первого роутера. В случае, если роутер не ответил
  26. # на пинг, этот блок (lease) отбрасывается.
  27. option routers 72.xxx.xxx.1;
  28. option dhcp-lease-time 1800;
  29. option dhcp-message-type 5;
  30. option domain-name-servers 127.0.0.1;
  31. option dhcp-server-identifier 72.xxx.xxx.xxx;
  32. # По документации следующие строки должны быть
  33. # в обязательном порядке. Время желательно
  34. # выставить как можно большее, чтобы не стало
  35. # просроченным.
  36. renew 2 2037/01/12 00:00:00;
  37. rebind 2 2037/01/12 00:00:00;
  38. expire 2 2037/01/12 00:00:00;
  39. }
Более подробно о других настройках можно прочитать в «man dhclient.conf»

понедельник, 8 июня 2009 г.

Работа Ubuntu Linux без носителя

Нужно было добиться загрузки Ubuntu в оперативную память компьютера и дальнейшей работы без носителя, с которого он был загружен. Решение получилось достаточно простым.
Вкратце идея такая: initrd.img изменяется так, чтобы, после загрузки и старта ядра, с носителя в память копировался файл со сжатым образом файловой системы корневого раздела (SquashFS). Далее поверх корневого раздела монтируется aufs-tmpfs и стартует Ubuntu.

Ниже будет описание как создать загрузочный iso-образ и бутовую USB-флешку.

  1. Создаем директории
    $ mkdir -p ~/ubuntu-ram/{etc,tmp,image,scripts}

  2. Устанавливаем необходимые пакеты
    $ sudo aptitude install lilo mtools genisoimage debootstrap syslinux squashfs-tools

  3. Копируем настройки initramfs
    Конфиги initramfs для iso-образа
    $ cp -a /etc/initramfs-tools ~/ubuntu-ram/etc/iso
    Конфиги initramfs для iso-образа
    $ cp -a /etc/initramfs-tools ~/ubuntu-ram/etc/usb

  4. Настраиваем окружение загружаемой системы
    $ export IMGROOT=~/ubuntu-ram/image
    $ sudo -E -s
    # debootstrap jaunty $IMGROOT http://mirror.ubuntu.optilink.ru/ubuntu/
    # echo "aufs / aufs rw 0 0" > $IMGROOT/etc/fstab
    # cp /etc/apt/sources.list $IMGROOT/etc/apt/
    # cp /etc/resolv.conf $IMGROOT/etc/
    # cat <<EOF > $IMGROOT/etc/hosts
    127.0.0.1 localhost.localdomain localhost
    127.0.1.1 hostname.domain hostname
    EOF

    # cat <<EOF > $IMGROOT/etc/network/interfaces
    auto lo
    iface lo loopback
    EOF

    # echo "hostname.domain" > $IMGROOT/etc/hostname
    # mount -t proc none $IMGROOT/proc
    # mount -o bind /dev $IMGROOT/dev
    # mount -t devpts none $IMGROOT/dev/pts
    # mount -t sysfs none $IMGROOT/sys
    Входим в изолированное окружение
    # chroot $IMGROOT bash
    Создаем аккаунт администратора и русскую локаль. Также разрешаем группе adm использование команды sudo
    # adduser --gecos 'System Administrator' demiurg
    # usermod -a -G adm demiurg
    # echo "@adm ALL=NOPASSWD: ALL" >> $IMGROOT/etc/sudoers
    # locale-gen ru_RU.UTF-8
    Устанавливаем ядро и требуемые утилиты
    # aptitude update
    # aptitude install linux-image-server grub aufs-tools squashfs-tools
    Настраиваем часовой пояс и консоль
    # dpkg-reconfigure tzdata
    # dpkg-reconfigure console-setup
    Далее система настраивается под себя (ставим дополнительные программы, правим конфиги под себя).

    Выходим из изолированного окружения
    # aptitude clean
    # exit
    Отмонтируем файловые системы
    # umount $IMGROOT/proc
    # umount $IMGROOT/dev/pts
    # umount $IMGROOT/dev
    # umount $IMGROOT/sys
    Выходим из режима суперпользователя
    # exit
    $

  5. Переходим к настройке конфигов initramfs для iso-образа
    Создаём так называемый хук (hook) - скрипт, вызываемый утилитой initramfs
    $ cat <<EOF > $IMGROOT/../etc/iso/hooks/load_modules
    1. #!/bin/sh
    2. set -e
    3. PREREQ=""
    4. prereqs () {
    5. echo "$PREREQ"
    6. }
    7. case $1 in
    8. prereqs)
    9. prereqs
    10. exit 0
    11. ;;
    12. esac
    13. . /usr/share/initramfs-tools/hook-functions
    14. force_load squashfs
    15. force_load isofs
    16. force_load aufs
    17. exit 0
    EOF
    $ chmod +x $IMGROOT/../etc/iso/hooks/load_modules
    Создаем скрипты, выполняющиеся во время загрузки initrd
    Скрипт, закидывающий образ системы в память
    $ cat <<EOF > $IMGROOT/../etc/iso/scripts/init-premount/udev_into_ram
    1. #!/bin/sh
    2. PREREQ=""
    3. prereqs () {
    4. echo "$PREREQ"
    5. }
    6. case $1 in
    7. prereqs)
    8. prereqs
    9. exit 0
    10. ;;
    11. esac
    12. mknod /dev/loop0 b 7 0
    13. mkdir /disk
    14. WAIT_COUNT=15
    15. while [ ! -e /dev/scd0 ] && [ "$WAIT_COUNT" -gt 0 ]
    16. do
    17. tmp=$((WAIT_COUNT-=1))
    18. sleep 1
    19. done
    20. echo -n "Please wait... "
    21. mount -t iso9660 -o ro /dev/scd0 /disk
    22. cp /disk/root.sqfs /
    23. echo "done"
    24. umount /disk && rm -Rf /disk
    EOF
    $ chmod +x $IMGROOT/../etc/iso/scripts/init-premount/udev_into_ram
    Скрипт, монтирующий файловую систему aufs
    $ cat <<EOF > $IMGROOT/../etc/iso/scripts/init-bottom/aufs_root
    1. #!/bin/sh
    2. #
    3. # https://help.ubuntu.com/community/aufsRootFileSystemOnUsbFlash
    4. #
    5. # Copyright 2008 Nicholas A. Schembri State College PA USA
    6. #
    7. # This program is free software: you can redistribute it and/or modify
    8. # it under the terms of the GNU General Public License as published by
    9. # the Free Software Foundation, either version 3 of the License, or
    10. # (at your option) any later version.
    11. #
    12. # This program is distributed in the hope that it will be useful,
    13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
    14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    15. # GNU General Public License for more details.
    16. #
    17. # You should have received a copy of the GNU General Public License
    18. # along with this program. If not, see
    19. # <http://www.gnu.org/licenses/>.
    20. # Thank you Voyage Linux for the idea, http://voyage.hk/ Great job on release 0.5
    21. #
    22. # Tested with 8.04.1
    23. #
    24. #
    25. # ****************************************************************************************
    26. #
    27. # Change log
    28. #
    29. # 2008.08.01 Added debugging comments in "drop to a shell" section. grub option aufs=tmpfs-debug will stop the init script.
    30. # reviewed *********** fix fstab on tmpfs ******************
    31. # rootaufs failed when system was booted with /dev/xxx and fstab had uuid= info.
    32. # BlaYO pointed out the best and simplest solution was to use grep -v. Grep replaces a sed one liner.
    33. # Add the comment block to fstab
    34. #
    35. #
    36. #
    37. case $1 in
    38. prereqs)
    39. exit 0
    40. ;;
    41. esac
    42. export aufs
    43. for x in $(cat /proc/cmdline); do
    44. case $x in
    45. root=*)
    46. ROOTNAME=${x#root=}
    47. ;;
    48. aufs=*)
    49. aufs=${x#aufs=}
    50. case $aufs in
    51. tmpfs-debug)
    52. aufs=tmpfs
    53. aufsdebug=1
    54. ;;
    55. esac
    56. ;;
    57. esac
    58. done
    59. if [ "$aufs" != "tmpfs" ]; then
    60. #not set in boot loader
    61. #I'm not loved. good bye
    62. exit 0
    63. fi
    64. # This is a simple overview of the steps needed to use aufs on the root file system and see the /rw and /ro branches.
    65. # initramfs init-botton script
    66. # move the root file system to aufs/unionfs readonly /ro
    67. # root is mounted on ${rootmnt}
    68. # create tmpfs on /rw
    69. # create a aufs using /ro and /rw
    70. # put some files on the tmpfs to fix mtab and fstab
    71. # move aufs to rootmnt to finish the init process.
    72. # No changes to the root file system are made by this script.
    73. #
    74. # Why!
    75. # This will allow you to use a usb flash drive and control what is written to the drive.
    76. # no need to rebuild the squashfs file just to add a program.
    77. # boot to single user mode. The system works the way you expect. boot aufs=tmpfs and no changes are written to the flash.
    78. # run ubuntu on an eeePC .
    79. # Install
    80. # Install ubuntu 8.04 Hardy. Hardy has aufs installed by default
    81. # apt-get update
    82. # apt-get dist-upgrade
    83. # apt-get install aufs-tools
    84. # echo aufs >> /etc/initramfs-tools/modules
    85. # put this file in /etc/initramfs-tools/scripts/init-bottom/rootaufs
    86. # chmod 0755 rootaufs
    87. # # clean up menu.lst
    88. # update-grub
    89. # update-initramfs -u
    90. # vi /boot/grub/menu.lst
    91. # add aufs=tmpfs to the default entry.
    92. # do not add this line to single user mode.
    93. # boot to single user mode in order to install software.
    94. # note: if your home account is on the root file system, your files are in ram and not saved.
    95. #
    96. echo
    97. echo " root-aufs: Setting up aufs on ${rootmnt} as root file system "
    98. echo
    99. modprobe -q --use-blacklist aufs
    100. if [ $? -ne 0 ]; then
    101. echo root-aufs error: Failed to load aufs.ko
    102. exit 0
    103. fi
    104. #make the mount points on the init root file system
    105. mkdir /aufs
    106. mkdir /rw
    107. mkdir /ro
    108. # mount the temp file system and move real root out of the way
    109. mount -t tmpfs aufs-tmpfs /rw
    110. mount --move ${rootmnt} /ro
    111. if [ $? -ne 0 ]; then
    112. echo root-aufs error: ${rootmnt} failed to move to /ro
    113. exit 0
    114. fi
    115. mount -t aufs -o dirs=/rw:/ro=ro aufs /aufs
    116. if [ $? -ne 0 ]; then
    117. echo root-aufs error: Failed to mount /aufs files system
    118. exit 0
    119. fi
    120. #test for mount points on aufs file system
    121. [ -d /aufs/ro ] || mkdir /aufs/ro
    122. [ -d /aufs/rw ] || mkdir /aufs/rw
    123. # the real root file system is hidden on /ro of the init file system. move it to /ro
    124. mount --move /ro /aufs/ro
    125. if [ $? -ne 0 ]; then
    126. echo root-aufs error: Failed to move /ro /aufs/ro
    127. exit 0
    128. fi
    129. # tmpfs file system is hidden on /rw
    130. mount --move /rw /aufs/rw
    131. if [ $? -ne 0 ]; then
    132. echo root-aufs error: Failed to move /rw /aufs/rw
    133. exit 0
    134. fi
    135. #*********** fix fstab on tmpfs ******************
    136. # test for /dev/sdx
    137. # this is not on the real file system. This is created on the tmpfs each time the system boots.
    138. # The init process will try to mount the root filesystem listed in fstab. / and swap must be removed.
    139. # the root file system must be mounted on /ro not on /
    140. if [ "$aufsdebug" -eq 1 ]; then
    141. echo " root-aufs debug: Remove the root file system and swap from fstab "
    142. echo
    143. echo
    144. echo " ROOTNAME $ROOTNAME "
    145. echo " resume $resume "
    146. echo
    147. echo ' BlaYO pointed out that grep can be used to quickly remove '
    148. echo ' the root file system from fstab. '
    149. echo
    150. echo ' Thank you BlaYO for the debug info.'
    151. echo
    152. fi
    153. # old code
    154. # I'm sure that sed can do this in one step but I want to correct on the rootname not matching the root in fstab.
    155. #cat /aufs/ro/etc/fstab|sed -e s/$ROOTNAME/\#$ROOTNAME/ -e s/$resume/\#$resume/ >/aufs/etc/fstab
    156. #Add the comment block to fstab
    157. cat <<EOF >/aufs/etc/fstab
    158. #
    159. # RootAufs has mounted the root file system in ram
    160. #
    161. # This fstab is in ram and the real fstab can be found /ro/etc/fstab
    162. # the root file system ' / ' has been removed.
    163. # All Swap files have been removed.
    164. #
    165. EOF
    166. #remove root and swap from fstab
    167. cat /aufs/ro/etc/fstab|grep -v ' / ' | grep -v swap >>/aufs/etc/fstab
    168. if [ $? -ne 0 ]; then
    169. echo root-aufs error: Failed to create /aufs/etc/fstab
    170. #exit 0
    171. fi
    172. # add the read only file system to fstab
    173. #ROOTTYPE=$(/lib/udev/vol_id -t ${ROOT})
    174. ROOTTYPE=$(cat /proc/mounts|grep ${ROOT}|cut -d' ' -f3)
    175. ROOTOPTIONS=$(cat /proc/mounts|grep ${ROOT}|cut -d' ' -f4)
    176. echo /dev/loop0 /ro squashfs ro,relatime 0 0 >>/aufs/etc/fstab
    177. # S22mount on debian systems is not mounting /ro correctly after boot
    178. # add to rc.local to correct what you see from df
    179. #replace last case of exit with #exit
    180. cat /aufs/ro/etc/rc.local|sed 's/\(.*\)exit/\1\#exit/' >/aufs/etc/rc.local
    181. echo mount -f /ro >>/aufs/etc/rc.local
    182. # add back the root file system. mtab seems to be created by one of the init proceses.
    183. echo "echo aufs / aufs rw,xino=/rw/.aufs.xino,br:/rw=rw:/ro=ro 0 0 >>/etc/mtab" >>/aufs/etc/rc.local
    184. echo "echo aufs-tmpfs /rw tmpfs rw 0 0 >>/etc/mtab" >>/aufs/etc/rc.local
    185. echo exit 0 >>/aufs/etc/rc.local
    186. #build remountrw
    187. echo \#!/bin/sh >/aufs/bin/remountrw
    188. echo mount -o remount,rw ${ROOT} >>/aufs/bin/remountrw
    189. chmod 0700 /aufs/bin/remountrw
    190. #build remountro
    191. echo \#!/bin/sh >/aufs/bin/remountro
    192. echo mount -o remount,ro ${ROOT} >>/aufs/bin/remountro
    193. chmod 0700 /aufs/bin/remountro
    194. # This should drop to a shell. (rewrite)
    195. if [ "$aufsdebug" -eq 1 ]; then
    196. echo
    197. echo " root-aufs debug: mount --move /aufs ${rootmnt} "
    198. echo
    199. echo ' root-aufs debug: init will stop here. '
    200. echo
    201. exit 0
    202. fi
    203. mount --move /aufs ${rootmnt}
    204. exit 0
    EOF
    $ chmod +x $IMGROOT/../etc/iso/scripts/init-bottom/aufs_root
    На этом настройка initramfs заканчивается.

  6. Создаём скрипт, создающий iso-образ и сохраняем его в файле «~/ubuntu-ram/scripts/make-iso.sh»
    1. #!/bin/sh
    2. WORKDIR=/path/to/ubuntu-ram
    3. SQUASHFS_ROOT=$WORKDIR/image/
    4. ISO_ROOT=$WORKDIR/tmp/
    5. rm -Rf $ISO_ROOT/*
    6. # Получаем версию ядра в окружении
    7. version=$(basename $(readlink $SQUASHFS_ROOT/initrd.img))
    8. version=${version#initrd.img-}
    9. mount -o bind $WORKDIR/etc/iso $SQUASHFS_ROOT/etc/initramfs-tools
    10. chroot $SQUASHFS_ROOT mkinitramfs -v -o /boot/initrd.img-$version $version
    11. umount $SQUASHFS_ROOT/etc/initramfs-tools
    12. mkdir $ISO_ROOT/isolinux
    13. cp $SQUASHFS_ROOT/boot/initrd.img-$version $ISO_ROOT/isolinux/initrd.gz
    14. cp $SQUASHFS_ROOT/boot/vmlinuz-$version $ISO_ROOT/isolinux/vmlinuz
    15. cp /usr/lib/syslinux/isolinux.bin $ISO_ROOT/isolinux/
    16. cat <<EOF > $ISO_ROOT/isolinux/isolinux.cfg
    17. DEFAULT server
    18. TIMEOUT 1
    19. LABEL server
    20. menu label ^Server
    21. kernel vmlinuz
    22. append initrd=initrd.gz root=/root.sqfs loop=/dev/loop0 rootfstype=squashfs aufs=tmpfs ro
    23. EOF
    24. #
    25. mksquashfs $SQUASHFS_ROOT $ISO_ROOT/root.sqfs \
    26. -e $SQUASHFS_ROOT/boot/* \
    27. $SQUASHFS_ROOT/initrd.img \
    28. $SQUASHFS_ROOT/vmlinuz
    29. # Создаём ISO
    30. mkisofs -o $WORKDIR/image.iso -r \
    31. -V "MYUSBSERVER" -v -no-emul-boot \
    32. -boot-load-size 4 -boot-info-table \
    33. -b isolinux/isolinux.bin \
    34. -c isolinux/isolinux.boot $ISO_ROOT
    Делаем его исполняемым
    $ chmod +x ~/ubuntu-ram/scripts/make-iso.sh
    После выполнения скрипта в директории «~/ubuntu-ram» будет создан требуемый iso-образ.

  7. Создание загрузочной USB флешки.
    Создаём хук
    $ cat <<EOF > ~/ubuntu-ram/etc/usb/hooks/load_modules
    1. #!/bin/sh
    2. set -e
    3. PREREQ=""
    4. prereqs () {
    5. echo "$PREREQ"
    6. }
    7. case $1 in
    8. prereqs)
    9. prereqs
    10. exit 0
    11. ;;
    12. esac
    13. . /usr/share/initramfs-tools/hook-functions
    14. force_load usb_storage
    15. force_load squashfs
    16. force_load vfat
    17. force_load aufs
    18. exit 0
    EOF
    $ chmod +x ~/ubuntu-ram/etc/usb/hooks/load_modules
    Копируем скрипт «etc/iso/scripts/init-bottom/aufs_root» в «etc/usb/scripts/init-bottom/aufs_root».
    Пишем скрипт, загружающий систему из USB-флешки в оперативную память
    $ cat <<EOF > ~/ubuntu-ram/etc/usb/scripts/init-premount/udev_into_ram
    1. #!/bin/sh
    2. PREREQ=""
    3. prereqs () {
    4. echo "$PREREQ"
    5. }
    6. case $1 in
    7. prereqs)
    8. prereqs
    9. exit 0
    10. ;;
    11. esac
    12. mknod /dev/loop0 b 7 0
    13. mkdir /disk
    14. WAIT_COUNT=15
    15. while [ ! -e /dev/disk/by-label/MYUSBSERVER ] && [ "$WAIT_COUNT" -gt 0 ]
    16. do
    17. tmp=$((WAIT_COUNT-=1))
    18. sleep 1
    19. done
    20. echo -n "Please wait... "
    21. mount -t vfat -o ro /dev/disk/by-label/MYUSBSERVER /disk
    22. cp /disk/root.sqfs /
    23. echo "done"
    24. umount /disk && rm -Rf /disk
    EOF
    $ chmod +x $IMGROOT/../etc/usb/scripts/init-premount/udev_into_ram
    Ниже приведён скрипт создающий бутовую USB-флешку. Скрипт сохраняется в файл «~/ubuntu-ram/scripts/make-usb.sh»
    1. #!/bin/sh
    2. WORKDIR=/path/to/ubuntu-ram
    3. SQUASHFS_ROOT=$WORKDIR/image/
    4. ISO_ROOT=$WORKDIR/tmp/
    5. rm -Rf $ISO_ROOT/*
    6. # Получаем версию ядра в окружении
    7. version=$(basename $(readlink $SQUASHFS_ROOT/initrd.img))
    8. version=${version#initrd.img-}
    9. mount -o bind $WORKDIR/etc/usb $SQUASHFS_ROOT/etc/initramfs-tools
    10. chroot $SQUASHFS_ROOT mkinitramfs -v -o /boot/initrd.img-$version $version
    11. umount $SQUASHFS_ROOT/etc/initramfs-tools
    12. mkdir $ISO_ROOT/isolinux
    13. cp $SQUASHFS_ROOT/boot/initrd.img-$version $ISO_ROOT/initrd.gz
    14. cp $SQUASHFS_ROOT/boot/vmlinuz-$version $ISO_ROOT/vmlinuz
    15. cat <<EOF > $ISO_ROOT/syslinux.cfg
    16. DEFAULT server
    17. TIMEOUT 1
    18. LABEL server
    19. menu label ^Server
    20. kernel vmlinuz
    21. append initrd=initrd.gz root=/root.sqfs loop=/dev/loop0 rootfstype=squashfs aufs=tmpfs ro
    22. EOF
    23. #
    24. mksquashfs $SQUASHFS_ROOT $ISO_ROOT/root.sqfs \
    25. -e $SQUASHFS_ROOT/boot/* \
    26. $SQUASHFS_ROOT/initrd.img \
    27. $SQUASHFS_ROOT/vmlinuz
    28. echo "Please insert USB flash drive and press Enter"
    29. read
    30. # /dev/sdX - Ваша USB-флешка
    31. lilo -M /dev/sdX
    32. lilo -A /dev/sdX 1
    33. mkfs.vfat /dev/sdX1
    34. syslinux -f /dev/sdX1
    35. mlabel -i /dev/sdX1 ::MYUSBSERVER
    36. mount -t vfat /dev/sdX1 /mnt
    37. cp -a $ISO_ROOT/* /mnt
    38. umount /mnt
    39. exit 0
    Делаем скрипт исполняемым
    $ chmod +x ~/ubuntu-ram/scripts/make-usb.sh