The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

СОВЕТЫ (Краткие заметки, Tips) (базовая разбивка)

   Безопасность
Ограничение доступа и безопасность Apache:
ipfw, IP-Filter:
iptables, ipchains:
Безопасность почтовой подсистемы:
Увеличение безопасности FreeBSD:
Увеличение безопасности Linux:
SSH
Виртуализация - Xen, OpenVZ, KVM, Qemu
Помещение программ в chroot
Шифрование, PGP

----* Определение IP-адреса пользователя в Telegram через голосовой вызов (доп. ссылка 1) (доп. ссылка 2)   [комментарии]
 
По умолчанию Telegram устанавливает прямой канал связи при осуществлении
голосового вызова пользователя, присутствующего в адресной книге (в настройках
можно выборочно отключить использование P2P и направлять трафик только через
внешний сервер). При инициировании соединения для обхода NAT в Telegram
применяется протокол STUN (Session Traversal Utilities for NAT), который
передаёт информацию об адресах звонящего и принимающего звонок в поле
XOR-MAPPED-ADDRESS. Соответственно, если в настройках "Security and Privacy" не
отключён P2P, звонящий может узнать IP-адрес того, кому адресован звонок. Метод
подойдёт и для любых других приложений, использующих STUN.

Для определения IP-адреса следует  во время осуществления вызова записать дамп
трафика в формате pcap, например, при помощи утилиты tcpdump или tshark, после
чего воспользоваться готовым скриптом
https://github.com/n0a/telegram-get-remote-ip/ или при помощи штатных утилит
проанализировать значение поля XOR-MAPPED-ADDRESS:

   tshark -w dump.pcap -a duration:5
   cat dump.pcap | 
     grep "STUN 106" | 
     sed 's/^.*XOR-MAPPED-ADDRESS: //' | 
     awk '{match($0,/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/); ip = substr($0,RSTART,RLENGTH); print ip}' |
     awk '!seen[$0]++'
 
----* Простое устройство для защиты данных в случае кражи ноутбука (доп. ссылка 1)   [комментарии]
 
Майкл Олтфилт (Michael Altfield) предложил простое и эффективное устройство
для блокирования доступа к конфиденциальным данным в случае кражи ноутбука с
активным пользовательским сеансом. Суть метода в контроле за подключением к
ноутбуку определённого USB-устройства, прикреплённого к владельцу (аналогично в
качестве признака можно использовать достижимость Bluetooth смартфона владельца
или метку RFID).


Во время работы в общественном месте или парке на ноутбуке активируется
специальное правило UDEV, которое контролирует активность подключения к
USB-устройству. В случае отсоединения USB-устройства (когда злоумышленник
выхватил ноутбук) UDEV-правило выполняет скрипт для завершения сеанса, удаления
каталога с конфиденциальными данными, шифрования данных или отмонтирования
шифрованного раздела.

Пример udev-правила для блокировки экрана при извлечении любого USB-устройства:

   sudo vi /etc/udev/rules.d/busKill.rules

   ACTION=="remove", SUBSYSTEM=="usb", RUN+="DISPLAY=:0 xscreensaver-command -lock"

   sudo udevadm control --reload


Для привязки к определённому USB-устройству необходимо узнать его идентификатор
(нужно подключить устройство, запустить udevadm monitor и извлечь устройство):
  
   udevadm monitor --environment --udev

   ACTION=remove
   ID_MODEL="Micromax_A74"
   SUBSYSTEM=usb

Модифицируем правило /etc/udev/rules.d/busKill.rules

   ACTION=="remove", SUBSYSTEM=="usb", ENV{ID_MODEL}=="Micromax_A74", RUN+="DISPLAY=:0 xscreensaver-command -lock"





Как вариант предложено дополнительно использовать магнитный разъединитель
USB-кабеля, подключённый до брелока с ключами шифрования данных. Далее брелок
подсоединяется цепочкой к одежде или руке владельца. При выдёргивании ноутбука
во время работы брелок с ключами шифрования остаётся у владельца, а UDEV-скрипт
экстренно выключает устройство.


   ACTION=="remove", SUBSYSTEM=="usb", ENV{ID_MODEL}=="Micromax_A74", RUN+="shutdown -h now"

Активировать правило блокировки можно автоматически при подключении
USB-устройства, добавив UDEV-правило с обработчиком ACTION=="bind"

   ACTION=="bind", SUBSYSTEM=="usb", ENV{ID_MODEL}=="Micromax_A74", RUN+="/root/killcord_on.sh"

/root/killcord_on.sh

   cat << EOF | tee /etc/udev/rules.d/busKill.rules
   ACTION=="remove", SUBSYSTEM=="usb", ENV{ID_MODEL}=="Micromax_A74", RUN+="shutdown -h now"
   EOF
   udevadm control --reload
 
----* Блокировка рекламы и вредоносных сайтов через /etc/hosts   [комментарии]
 
Проект github.com/StevenBlack/hosts предлагает простой подход для блокировки
рекламы и вредоносных сайтов, не требующий установки дополнений и работающий в
любых операционных системах и браузерах. Суть метода в размещении черного
списка с доменами рекламных сетей в файле /etc/hosts. При попытке загрузки
рекламного блока имя связанного с ним домена резолвится в несуществующий адрес
0.0.0.0 и реклама не отображается из-за недоступности сервера.

Адрес 0.0.0.0 используется вместо обычно практикуемого 127.0.0.1 так как
попытка соединения с ним сразу возвращает ошибку без ожидании истечения
таймаута. В настоящее время в БД находится более 27 тысяч записей, составленных
на основе популярных публичных списков блокировки, в том числе  adaway.org, mvps.org,
malwaredomains.com, someonewhocares.org и yoyo.org. При этом
разработчики пытаются добиться разумного компромисса, избежать ложных
срабатываний и слишком большого разрастания базы (например, похожий список
http://hosts-file.net содержит более 300 тысяч записей).

Список постоянно обновляется, поэтому для поддержания /etc/hosts в актуальном
состоянии предлагается специальный скрипт updateHostsFile.py, который можно
прописать в crontab, а можно время от времени запускать вручную.

После обновления /etc/hosts следует перезапустить службу резолвинга:

Debian/Ubuntu 
   
   sudo /etc/rc.d/init.d/nscd restart

Fedora Linux, Arch Linux, Manjaro:

   sudo systemctl restart NetworkManager.service

Другие Linux с systemd: 

   sudo systemctl restart network.service

OS X:

   sudo dscacheutil -flushcache
   sudo killall -HUP mDNSResponder

Windows:

   ipconfig /flushdns
 
----* Перенаправление на HTTPS при помощи HSTS в Apache, NGINX и Lighttpd (доп. ссылка 1)   [комментарии]
 
Протокол HSTS (HTTP Strict Transport Security) позволяет администратору сайта
указать на необходимость обращения только по HTTPS и автоматизировать проброс
на HTTPS при изначальном обращении по ссылке на HTTP. Управление производится
при помощи HTTP-заголовка Strict-Transport-Security, который выдаётся при
обращении по HTTPS (при выдаче по HTTP заголовок игнорируется) и указывает
браузеру на необходимость оставаться в зоне HTTPS даже при переходе по ссылкам
"http://". Замена http:// на https:// будет автоматически выполняться при
обращении к защищаемому ресурсу с внешних сайтов, а не только для внутренних ссылок.

Использование в Apache:

При помощи mod_headers устанавливаем для HTTPS-блока виртуального хоста
заголовок Strict-Transport-Security (max-age - срок действия (1 год),
includeSubdomains - распространять замену http:// на https:// для всех
поддоменов; preload - занести в поддерживаемый браузером статический список).
Дополнительно устанавливаем заголовок "X-Frame-Options: DENY" для запрета
встраивания контента сайта в блоки iframe.

   LoadModule headers_module modules/mod_headers.so

   <VirtualHost 192.168.1.1:443>
      Header always set Strict-Transport-Security "max-age= 31536000; includeSubdomains; preload"
      Header always set X-Frame-Options DENY
   </VirtualHost>

Для HTTP-блока хоста настраиваем редирект:

   <VirtualHost *:80>
     <IfModule mod_rewrite.c>
       RewriteEngine On
       RewriteCond %{HTTPS} off
       RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
     </IfModule>
    </VirtualHost>

Настройка в nginx:

Добавляем в блок server:

    add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
    add_header X-Frame-Options "DENY";

Настройка в Lighttpd:
 
   server.modules += ( "mod_setenv" )
   $HTTP["scheme"] == "https" {
       setenv.add-response-header  = ( "Strict-Transport-Security" => "max-age=63072000; includeSubdomains; preload",  "X-Frame-Options" => "DENY")
   }
 
----* Пример поиска подозрительных php-файлов, содержащих очень длинные строки   Автор: 100RAGE1  [комментарии]
 
Некоторые вирусные php-файлы содержат очень длинные строки в коде. Такие файлы
можно поискать однострочником:

   find ./ -name "*.php" -print0 |  wc -L --files0-from=- | sort -V | grep -E "^[0-9]{5,}+ \\./"

найденные файлы можно просмотреть визуально или проверить чем-то еще.
 
----* Использование systemtap для устранения уязвимости в реализации /proc/pid/mem (доп. ссылка 1)   [комментарии]
 
Для устранения уязвимости CVE-2012-0056 в /proc/pid/mem без обновления ядра
Linux можно использовать systemtap для ограничения системного вызова. Systemtap
из коробки доступен в RHEL/CentOS и может быть установлен из репозитория в
Debian/Ubuntu. Без systemtap обходным путем решения проблемы является
блокирования доступа пользователя на запуск setuid-программ.

Проверим, уязвима ли наша система. Для этого загружаем, собираем и запускаем
специальную проверочную утилиту:

   $ wget http://grsecurity.net/~spender/correct_proc_mem_reproducer.c
   $ make correct_proc_mem_reproducer
   $ ./correct_proc_mem_reproducer
   vulnerable

Рассмотрим процесс установки и использования systemtap в Ubuntu и Debian.

Установим systemtap и пакет для отладки ядра (занимает около 2 Гб)

Debian:

   sudo apt-get install -y systemtap linux-image-$(uname -r)-dbg

Ubuntu (требуется подключение отладочного репозитория):

   sudo apt-get install -y lsb-release
   echo "deb http://ddebs.ubuntu.com/ $(lsb_release -cs) main restricted universe multiverse" | \\
     tee -a /etc/apt/sources.list.d/ddebs.list
   sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys ECDCAD72428D7C01
   sudo apt-get update
   sudo apt-get install -y systemtap linux-image-$(uname -r)-dbgsym

Если в процессе выполнения "apt-get update" выведена ошибка, загружаем и
устанавливаем отладочные пакеты с ядром вручную:

   sudo apt-get install -y systemtap dpkg-dev
   wget http://ddebs.ubuntu.com/pool/main/l/linux/$(dpkg -l linux-image-$(uname -r) | \\
      grep ^ii | awk '{print $2 "-dbgsym_" $3}' | tail -n1)_$(dpkg-architecture -qDEB_HOST_ARCH).ddeb
   sudo dpkg -i linux-image-$(uname -r)-dbgsym.ddeb

Создаём systemtap-скрипт proc-pid-mem.stp для блокирования уязвимости (в
функции mem_write изменяем на ноль значение аргумента count, определяющего
размер записываемых данных):

   probe kernel.function("mem_write@fs/proc/base.c").call {
           $count = 0
   }

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

   sudo stap -Fg proc-pid-mem.stp

Убедимся, что уязвимость теперь не проявляется:

   $ ./correct_proc_mem_reproducer
   not vulnerable


Чтобы каждый раз не компилировать модуль systemtap, можно собрать его загодя:

   stap -g -m cve_2012_0056 proc-pid-mem.stp -p4

(опция  "-g" включает режим гуру, при котором допускается изменение параметров
функций, опция -m cve_2012_0056 задаёт имя модуля, -p4 указывает на
необходимость остановиться на 4 шаге и не загружать модуль)

Копируем созданный модуль в область с модулями ядра:

   mkdir /lib/modules/$(uname -r)/systemtap
   cp cve_2012_0056.ko /lib/modules/$(uname -r)/systemtap

Запускаем модуль:

   staprun -L cve_2012_0056

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

По аналогии можно вклиниваться в работу других системных вызовов. Некоторые 
примеры:



   Запрет на создание файлов с определённым именем:
   #!/usr/bin/env stap
   # badname.stp
   # Prevent the creation of files with undesirable names.
   # Source: http://blog.cuviper.com/2009/04/08/hacking-linux-filenames/

   # return non-zero if the filename should be blocked
   function filter:long (name:string)
   {
     return isinstr(name, "XXXbadnameXXX")
   }

   global squash_inode_permission
   probe kernel.function("may_create@fs/namei.c")
   {
     # screen out the conditions which may_create will fail anyway
     if ($child->d_inode || $dir->i_flags & 16) next

     # check that the new file meets our naming rules
     if (filter(kernel_string($child->d_name->name)))
       squash_inode_permission[tid()] = 1
   }
   probe kernel.function("inode_permission@fs/namei.c").return !,
         kernel.function("permission@fs/namei.c").return
   {
   if (!$return && squash_inode_permission[tid()])
     $return = -13 # -EACCES (Permission denied)
     delete squash_inode_permission[tid()]
   }


Блокирование работы ptrace: http://sourceware.org/systemtap/examples/process/noptrace.stp

Вывод в лог дополнительных данных о всех TCP-соединениях:

   #! /usr/bin/env stap

   probe begin {
     printf("%6s %16s %6s %6s %16s\\n",
         "UID", "CMD", "PID", "PORT", "IP_SOURCE")
   }

   probe kernel.function("tcp_accept").return?,
         kernel.function("inet_csk_accept").return? {
     sock = $return
     if (sock != 0)
       printf("%6d %16s %6d %6d %16s\\n", uid(), execname(), pid(),
           inet_get_local_port(sock), inet_get_ip_source(sock))
   }

Вывод деталей о входе и выходе из функции ядра:

   #! /usr/bin/env stap
   # Simple probe to detect when a process is waiting for more socket send
   # buffer memory. Usually means the process is doing writes larger than the
   # socket send buffer size or there is a slow receiver at the other side.
   # Increasing the socket's send buffer size might help decrease application
   # latencies, but it might also make it worse, so buyer beware.
   #
   # Typical output: timestamp in microseconds: procname(pid) event
   #
   # 1218230114875167: python(17631) blocked on full send buffer
   # 1218230114876196: python(17631) recovered from full send buffer
   # 1218230114876271: python(17631) blocked on full send buffer
   # 1218230114876479: python(17631) recovered from full send buffer

   probe kernel.function("sk_stream_wait_memory")
   {
  	printf("%u: %s(%d) blocked on full send buffer\\n",
		gettimeofday_us(), execname(), pid())
   }

   probe kernel.function("sk_stream_wait_memory").return
   {
	printf("%u: %s(%d) recovered from full send buffer\\n",
		gettimeofday_us(), execname(), pid())
   }
 
----* Проверка Linux-системы на наличие следов взлома (доп. ссылка 1) (доп. ссылка 2)   [комментарии]
 
В процессе разбора истории со взломом  kernel.org было выявлено, что
атаковавшим удалось установить вредоносное ПО на Linux-машины некоторых
разработчиков, используя которое были перехвачены ключи доступа. В списке
рассылки разработчиков ядра Linux опубликована краткая инструкция по
проверке целостности системы и выявлению следов активности злоумышленников.
Суть опубликованных рекомендаций изложена ниже.

Одним из очевидных способов гарантировать чистоту системы от активности
злоумышленников является переустановка системы с нуля. Но прежде чем прибегнуть
к переустановке, следует убедиться, что система действительно поражена. Чтобы
обеспечить выявление скрывающих свое присутствие руткитов проверку желательно
выполнять загрузившись с LiveCD.


1. Установка и запуск специализированных инструментов для выявления руткитов, например,
chkrootkit, ossec-rootcheck и rkhunter.
При запуске утилиты rkhunter возможно ложное срабатывание на некоторых системах
с Debian. Вызывающие ложные срабатывания факторы описаны в файле /usr/share/doc/rkhunter/README.Debian.gz


2. Проверка корректности сигнатур для всех установленных в системе пакетов.
Для дистрибутивов на базе RPM:

   rpm --verify --all

Для дистрибутивов с dpkg следует использовать скрипт:

   dpkg -l \*|while read s n rest; do if [ "$s" == "ii" ]; then echo $n;
   fi; done > ~/tmp.txt
   for f in `cat ~/tmp.txt`; do debsums -s -a $f; done

Утилиту debsums следует установить отдельно:
   sudo apt-get install debsums

Вывод измененных файлов:
   debsums -ca

Вывод измененных файлов конфигурации:
   debsums -ce

Посмотреть пакеты без контрольных сумм:
   debsums -l

Другой вариант контрольных сумм для файлов в Debian:

   cd /var/lib/dpkg/info
   cat *.md5sums | sort > ~/all.md5
   cd /
   md5sum -c ~/all.md5 > ~/check.txt 2>&1
   

3. Проверка на то, что установленные пакеты действительно подписаны
действующими цифровыми подписями дистрибутива.

Для систем на базе пакетного менеджера RPM:

   for package in `rpm -qa`; do
      sig=`rpm -q --qf '%{SIGPGP:pgpsig}\n' $package`
      if [ -z "$sig" ] ; then
         # check if there is a GPG key, not a PGP one
         sig=`rpm -q --qf '%{SIGGPG:pgpsig}\n' $package`
         if [ -z "$sig" ] ; then
             echo "$package does not have a signature!!!"
         fi
     fi
   done



4. При выявлении подозрительных пакетов их желательно удалить и установить заново.

Например, для переустановки ssh в дистрибутивах на базе RPM следует выполнить:

	/etc/init.d/sshd stop
	rpm -e openssh
	zypper install openssh	# для openSUSE
	yum install openssh	# для Fedora

Рекомендуется проделать эти операции, загрузившись с LiveCD и используя опцию 'rpm --root'.

5. Проверка целостности системных скриптов в /etc/rc*.d и выявление
подозрительного содержимого в /usr/share. Эффективность выполнения проверок
можно гарантировать только при загрузке с LiveCD.

Для выявления директорий в /usr/share, которые не принадлежат каким-либо
пакетам в дистрибутивах на базе RPM можно использовать следующий скрипт:

   for file in `find /usr/share/`; do
      package=`rpm -qf -- ${file} | grep "is not owned"`
      if [ -n "$package" ] ; then
         echo "weird file ${file}, please check this out"
      fi
   done

В Debian для определения какому пакету принадлежит файл следует использовать "dpkg-query -S":

   for file in `find /usr/share/GeoIP`; do
      package=`dpkg-query -S ${file} 2>&1 | grep "not found"`
      if [ -n "$package" ] ; then
         echo "weird file ${file}, please check this out"
      fi
   done


Аудит suid root программ:

   find / -user root -perm -4000 -ls

6. Проверка логов на предмет наличия нетипичных сообщений:

* Проверить записи в wtmp и /var/log/secure*, обратив особое внимание на
соединения с внешних хостов.
* Проверить упоминание обращения к /dev/mem;
* В /var/log/secure* посмотреть нет ли связанных с работой ssh строк с не
текстовой информацией в поле версии, которые могут свидетельствовать о попытках взлома.
* Проверка удаления файлов с логами, например, может не хватать одного файла с ротацией логов.
* Выявление подозрительных соединений с локальной машины во вне, например,
отправка email или попытки соединения по ssh во время вашего отсутствия.
* Анализ логов пакетного фильтра с целью выявления подозрительных исходящих
соединений. Например, даже скрытый руткитом бэкдор может проявить себя в логах
через резолвинг DNS. Общая рекомендация сводится к контролю на промежуточном
шлюзе соединений во вне для только принимающих внешние соединения машин и
соединений из вне для только отправляющих запросы клиентских машин.

7. Если в процессе проверки обнаружен факт проникновения злоумышленника следует
сделать копию дисковых разделов на отдельный носитель при помощи команды "dd" с
целью более подробного анализа методов проникновения. Только после этого можно
полностью переустановить всю систему с нуля. Одновременно нужно поменять все
пароли и ключи доступа, уведомив об инциденте администраторов серверов, на
которых осуществлялась удаленная работа.
 
----* Совместное использование SELinux и iptables (доп. ссылка 1)   [комментарии]
 
Используя утилиту Secmark можно организовать назначение в правилах iptables
SELinux-меток для сетевых пакетов, примерно также как осуществляется назначение
меток для локальных системных ресурсов. Подобное может использоваться для
предотвращения доступа сторонних процессов, не находящихся под контролем
SELinux, к определенному классу пакетов. Например, можно указать что запросы на
80 порт (метка http_packet_t) может отправлять только определенный web-браузер
(или процесс, имеющий SELinux-метку http_t) и никто иной.

По умолчанию все сетевые пакеты снабжаются меткой unlabeled_t, а для всех
подконтрольных процессов активируется правило, без ограничений разрешающее
отправку и прием пакетов:

   allow MYDOMAIN unlabed_t:packet { send recv };

При назначении меток для трафика при помощи Secmark разрешительная политика по
отношению к unlabed_t может привести к тому, что в случае отключения пакетного
фильтра или в момент его перезапуска, правила блокирования будут временно проигнорированы.

Попытаемся отключить автоматическую установку метки unlabeled_t, которая
назначается в Fedora Linux через SELinux-модуль unlabelednet. Если отключить
данный набор SELinux-политик, то все подконтрольные SELinux приложения потеряют
возможность отправлять и принимать пакеты с меткой unlabeled_t. Чтобы вернуть
таким программам возможность работы в сети для них необходимо подготовить
соответствующие SELinux-правила и пометить пакеты.


Для усиления защиты ноутбука было решено подготовить простые SELinux-политики,
запрещающие обращаться к внешним сетевым ресурсам всем системным сервисам,
ограниченным при помощи SELinux. Всем программ, запущенные в рамках сессии
пользователя, разрешено обращаться как ко внутренним, так и к внешним сетевым ресурсам.

Подготовлено три политики доступа к сети:

internal_packet_t: Iptables помечает меткой internal_packet_t все пакеты,
отправленные в локальную сеть или приходящие на текущую машину из локальной сети;

dns_external_packet_t: Iptables помечает меткой dns_external_packet_t все
внешние обращения к DNS-серверам (udp/tcp порт 53);

external_packet_t: Iptables помечает меткой external_packet_t все остальные
пакеты, не подпадающие под первые два правила;


Для упрощения генерации iptables-правил для назначения SELinux-меток был создан скрипт
secmarkgen:

  #!/bin/sh -e

  init() {
  # This just tells iptables to apply the same label to incoming packets as it did on outgoing
    echo $IPTABLES -F -t security
    echo $IPTABLES -t security -A INPUT -m state --state ESTABLISHED,RELATED -j CONNSECMARK --restore
 
  # Apply a label even if its on another port but is related
    echo $IPTABLES -t security -A OUTPUT -m state --state ESTABLISHED,RELATED -j CONNSECMARK --restore
    echo 
    return

  }

  start() {
    # Create a chain for each class of packets we have.
    echo "$IPTABLES -t security -X $NAME 2> /dev/null"
    echo "$IPTABLES -t security -N $NAME"
  }

  fini() {
    # Label all other packets going internally to $TYPE:$MCS
    echo $IPTABLES -t security -A $NAME -j SECMARK --selctx system_u:object_r:$TYPE:$MCS
    echo $IPTABLES -t security -A $NAME -j CONNSECMARK --save
    echo $IPTABLES -t security -A $NAME -j ACCEPT
    echo 
  }

  setup_network() {

    if [ ! -z "$PORTS" ]; then
	if [ ! -z "$NETWORK" ]; then
            # Send packets going to an $NET httpd to the $NAME chain
	    echo $IPTABLES -A OUTPUT -t security -p $PROTOCOL -d $NETWORK --dport $PORTS -j $NAME
	    echo $IPTABLES -A INPUT -t security -p $PROTOCOL -d $NETWORK --sport $PORTS -j $NAME
	else
            # Send packets going to $PORTS httpd to the $NAME chain
	    echo $IPTABLES -A OUTPUT -t security -p $PROTOCOL --dport $PORTS -j $NAME
	    echo $IPTABLES -A INPUT -t security -p $PROTOCOL --sport $PORTS -j $NAME
	fi
    elif [ ! -z "$NETWORK" ]; then
            # Send packets going to $PORT httpd to the $NAME chain
	    echo $IPTABLES -A OUTPUT -t security -d $NETWORK -j $NAME
	    echo $IPTABLES -A INPUT -t security -s $NETWORK -j $NAME
    else
	echo $IPTABLES -A OUTPUT -t security -j $NAME
	echo $IPTABLES -A INPUT -t security -j $NAME
    fi
  }
  usage() {
      	 $"""
  Usage: $0 -i
  Usage: $0 -T iptablescmd -P protocol -p port[:...] -N network[,...] -t selinux_type -m MCS NAME
  Usage: $0 -f NAME
  """
  }

  echo
  echo "#---------------"
  echo "# $0 $*"
  echo "#---------------"
  echo
  IPTABLES=iptables
  NAME=
  PORTS=
  MCS=s0
  NETWORK=
  TYPE=client_packet_t
  PROTOCOL=tcp
  FINISH=0
  START=0
  INIT=0

  while getopts "sfin:p:m:t:T:P:" i; do
    case "$i" in
	i)
	    INIT=1
	    ;;
	s)
	    START=1
	    ;;
	f)
	    FINISH=1
	    ;;
	P)
	    PROTOCOL=$OPTARG
	    ;;
	T)
	    IPTABLES=$OPTARG
	    ;;
	n)
	    export NETWORK=$OPTARG
	    ;;
	t)
	    export TYPE=$OPTARG
	    ;;
	p)
	    export PORTS=$OPTARG
	    ;;
	m)
	    export MCS=$OPTARG
	    ;;
	*)
	    usage
	    exit 1
  esac
  done

  # Init does not require a NAME
  if [ $INIT == 1 ]; then 
    init
    exit $?
  fi

  # Move out processed options from arguments
  shift $(( OPTIND - 1 ))

  NAME=$1

  if [ -z "$NAME" -o -z "$MCS" -o -z "$NAME" ]; then
	usage
	exit 1
  fi

  if [ $START == 1 ]; then 
    start
    exit $?
  fi

  if [ $FINISH == 1 ]; then 
    fini
    exit $?
  fi

  setup_network


Скрипт можно запускать со следующими параметрами:

Инициализируем secmark-метки:
   ./secmarkgen -i

Определяем имя сети (имя Iptables-цепочки):
   ./secmarkgen -s INTERNAL


Привязываем к созданной цепочке набор правил. Синтаксис команды:
   ./secmarkgen -T iptablescmd -P protocol -p port[:...] -N network[,...] -t selinux_type -m MCS NAME

Например:

   ./secmarkgen -n 255.255.255.255,127/8,10.0.0.0/8,172.16.0.0/16,224/24,192.168/16 INTERNAL

Для завершения формирования secmark-правил и их привязки к определенной
SELinux-метке используется команда:

   ./secmarkgen -f NAME

Например, 

   ./secmarkgen -f -t internal_packet_t INTERNAL

в итоге будет сгенерирован примерно такой скрипт:

   #--------------------
   # ./secmarkgen -i
   #--------------------
   iptables -F -t security

   iptables -t security -A INPUT -m state --state ESTABLISHED,RELATED -j CONNSECMARK --restore

   iptables -t security -A OUTPUT -m state --state ESTABLISHED,RELATED -j CONNSECMARK --restore

   #--------------------
   # ./secmarkgen -s INTERNAL
   #--------------------

   iptables -t security -X INTERNAL 2> /dev/null

   iptables -t security -N INTERNAL

   #--------------------
   # ./secmarkgen -n 255.255.255.255,127/8,10.0.0.0/8,172.16.0.0/16,224/24,192.168/16 INTERNAL
   #--------------------

   iptables -A OUTPUT -t security -d 255.255.255.255,127/8,10.0.0.0/8,172.16.0.0/16,224/24,192.168/16 -j INTERNAL

   iptables -A INPUT -t security -s 255.255.255.255,127/8,10.0.0.0/8,172.16.0.0/16,224/24,192.168/16 -j INTERNAL

   #--------------------
   # ./secmarkgen -f -t internal_packet_t INTERNAL
   #--------------------

   iptables -t security -A INTERNAL -j SECMARK --selctx system_u:object_r:internal_packet_t:s0

   iptables -t security -A INTERNAL -j CONNSECMARK --save

   iptables -t security -A INTERNAL -j ACCEPT


Для генерации iptables-правил для локальных приложений используется примерно
такой скрипт (secmark_test.sh):

   ./secmarkgen -i
   ./secmarkgen -s INTERNAL
   ./secmarkgen -n 255.255.255.255,127/8,10.0.0.0/8,172.16.0.0/16,224/24,192.168/16 INTERNAL
   ./secmarkgen -f -t internal_packet_t INTERNAL
   ./secmarkgen -s DNS
   ./secmarkgen -P udp -p 53 DNS
   ./secmarkgen -P tcp -p 53 DNS
   ./secmarkgen -f -t dns_external_packet_t DNS
   ./secmarkgen -s EXTERNAL
   ./secmarkgen EXTERNAL
   ./secmarkgen -f -t external_packet_t EXTERNAL
   ./secmarkgen -T ip6tables -i
   ./secmarkgen -T ip6tables -s INTERNAL
   ./secmarkgen -T ip6tables -n FEC0::/10,::1/128,FF::/8,FE80::/10FC00::/7 INTERNAL
   ./secmarkgen -T ip6tables -f -t internal_packet_t INTERNAL
   ./secmarkgen -T ip6tables -s EXTERNAL
   ./secmarkgen -T ip6tables EXTERNAL
   ./secmarkgen -T ip6tables -f -t external_packet_t EXTERNAL
   
Генерируем соответствующие iptables-правила:

   ./secmark_test.sh > /tmp/rules

Устанавливать данные iptables-правила пока рано, вначале нужно определить
соответствующие указанным меткам (*_packet_t) SELinux-политики, без которых
использование данных меток в iptables приведет к выводу ошибки.

Формируем файл с SELinux-политиками (secmark.te):

   policy_module(secmark, 1.0)

   gen_require('

      attribute domain;

      attribute sysadm_usertype;

      # Domains that a staff user could transition to

      attribute staff_usertype;

      attribute telepathy_domain;

      type ping_t;

      type vpnc_t;

      type ssh_t;
  
      type nsplugin_t;

      type mozilla_plugin_t;

      # System domains that want to talk to the external network

      type ntpd_t;

      type sssd_t;

   ')

   # Type Definitions

   attribute external_packet;

   type internal_packet_t;

   corenet_packet(internal_packet_t)

   type dns_external_packet_t, external_packet;

   corenet_packet(dns_external_packet_t)

   type external_packet_t, external_packet;

   corenet_packet(external_packet_t)

   # Allow Rules

   allow domain internal_packet_t:packet { recv send };

   allow sysadm_usertype external_packet:packet { recv send };

   allow staff_usertype external_packet:packet { recv send };

   allow vpnc_t external_packet:packet { recv send };

   allow ssh_t external_packet:packet { recv send };

   allow mozilla_plugin_t external_packet:packet { recv send };

   allow nsplugin_t external_packet:packet { recv send };

   allow telepathy_domain external_packet:packet { recv send };

   allow ping_t external_packet:packet { recv send };

   allow ntpd_t external_packet:packet { recv send };

   dontaudit sssd_t dns_external_packet_t:packet { recv send };


Рассмотрим правила более подробно.
Строка

   policy_module(secmark, 1.0)

определяет имя модуля с политиками. 

Далее следует список требований

   gen_require('

      attribute domain;
      ... 
      type sssd_t;
   ')

При написании SELinux-политики необходимо сослаться на все типы и атрибуты,
чтобы их можно было использовать в правилах. Подобные ссылки указываются в
блоке gen_requires. Одновременно можно определить новые типы. Если один из
определенных в gen_requires атрибутов или типов будет не определен в других
частях правил, SELinux не активирует созданную политику. Например, атрибут
staff_usertype предоставляется всем обслуживающим пользовательским процессам,
sysadm_usertype присваивается всем процессам, используемым при
администрировании, домен telepathy_domain охватывает все приложения, связанные
с фреймворком telepathy.

Далее, в файле следуют правила определения типов и групп. Создаем атрибут
external_packet для группировки всех  правил, связанных с внешним трафиком.
Также создаем интерфейс corenet_packet для ассоциации набора правил с пакетами.

   attribute external_packet;
   type internal_packet_t;
   corenet_packet(internal_packet_t)
   type dns_external_packet_t, external_packet;
   corenet_packet(dns_external_packet_t)
   type external_packet_t, external_packet;
   corenet_packet(external_packet_t)
  

Далее указано правило, разрешающее всем процессам отправку и прием внутренних
пакетов из локальной сети:

   allow domain internal_packet_t:packet { recv send };

Следующее правило позволяет запускаемым администраторами программам отправлять
и принимать пакеты из внешних сетей (вместо указания  xternal_packet_t в
правиле фигурирует атрибут external_packet, который позволяет провести действие
сразу над группой -  external_packet_t и dns_external_packet_t):


   allow sysadm_usertype external_packet:packet { recv send };
   allow staff_usertype external_packet:packet { recv send };
   allow vpnc_t external_packet:packet { recv send };
   allow ssh_t external_packet:packet { recv send };
   allow mozilla_plugin_t external_packet:packet { recv send };
   allow nsplugin_t external_packet:packet { recv send };
   allow telepathy_domain external_packet:packet { recv send };
   allow ping_t external_packet:packet { recv send };

Для сервиса ntpd заведен отдельный тип ntp_external_packet_t:

   allow ntpd_t external_packet:packet { recv send };

Для программы sssd запрещаем общение с системами за пределами приватной сети:

   dontaudit sssd_t dns_external_packet_t:packet { recv send };




Теперь приступим к компиляции, установке и применению созданной SELinux-политики:

Компилируем:

   make -f /usr/share/selinux/devel/Makefile

Устанавливаем:

   semodule -i secmark.pp

Активируем iptables-правила:

   sh /tmp/rules

Сохраняем внесенные изменения:

   service iptables save
   service ip6tables save

С этого момента каждому сетевому пакету присваивается одна из трех созданных
SELinux-меток. Для отладки следует проследить за появлением avc-сообщений и при
необходимости добавить исключения с использованием правил allow/dontaudit или
расследовать причину появления непрошеного трафика.
 
----* Замена setuid-бита на capabilities для системных программ в Linux (доп. ссылка 1)   [комментарии]
 
С целью избавления системы от программ с suid-битом, можно использовать следующую инструкцию.
Для привязки capabilities к исполняемому файлу используется утилита setcap из пакета libcap2-bin:

   sudo apt-get install libcap2-bin

Для формирования списка setuid-root и setgid-root программ можно использовать следующие команды:

   find /bin /sbin /lib /usr/bin /usr/sbin /usr/lib -perm /4000 -user root
   find /bin /sbin /lib /usr/bin /usr/sbin /usr/lib -perm /2000 -group root

Команды для замены setuid/setgid для базовых пакетов:

coreutils

   chmod u-s /bin/su
   setсap cap_setgid,cap_setuid+ep /bin/su

dcron

   chmod u-s /usr/bin/crontab
   setcap cap_dac_override,cap_setgid+ep /usr/bin/crontab

inetutils

   chmod u-s /usr/bin/rsh
   setcap cap_net_bind_service+ep /usr/bin/rsh

   chmod u-s /usr/bin/rcp
   setcap cap_net_bind_service+ep /usr/bin/rcp

   chmod u-s /usr/bin/rlogin
   setcap cap_net_bind_service+ep /usr/bin/rlogin

iputils

   chmod u-s /bin/ping
   setcap cap_net_raw+ep /bin/ping

   chmod u-s /bin/ping6
   setcap cap_net_raw+ep /bin/ping6

   chmod u-s /bin/traceroute
   setcap cap_net_raw+ep /bin/traceroute

   chmod u-s /bin/traceroute6
   setcap cap_net_raw+ep /bin/traceroute6

pam

   chmod u-s /sbin/unix_chkpwd
   setcap cap_dac_read_search+ep /sbin/unix_chkpwd

shadow

   chmod u-s /usr/bin/chage
   setcap cap_dac_read_search+ep /usr/bin/chage

   chmod u-s /usr/bin/chfn
   setcap cap_chown,cap_setuid+ep /usr/bin/chfn

   chmod u-s /usr/bin/chsh
   setcap cap_chown,cap_setuid+ep /usr/bin/chsh

   chmod u-s /usr/bin/expiry
   setcap cap_dac_override,cap_setgid+ep /usr/bin/expiry

   chmod u-s /usr/bin/gpasswd
   setcap cap_chown,cap_dac_override,cap_setuid+ep /usr/bin/gpasswd

   chmod u-s /usr/bin/newgrp
   setcap cap_dac_override,cap_setgid+ep /usr/bin/newgrp

   chmod u-s /usr/bin/passwd
   setcap cap_chown,cap_dac_override,cap_fowner+ep /usr/bin/passwd

xorg-xserver

   chmod u-s /usr/bin/Xorg
   setcap cap_chown,cap_dac_override,cap_sys_rawio,cap_sys_admin+ep /usr/bin/Xorg


screen - обязательно требует setuid для выполнения определенных проверок

util-linux-ng - не рекомендуется использовать данный пакет с capabilities, так
как в реализации команд mount и umount присутствуют определенные проверки,
которые действуют только с setuid и пропускаются с  capabilities, что дает
возможность пользователям монтировать файловые системы к которым они не имеют доступа.
Подробнее об опасностях, которые сулит перевод программы с setuid на
capabilities без проведения аудита кода, можно прочитать здесь.
 
----* Проблемы с Evince при использовании нестандартного пути к домашней директории в Ubuntu   [комментарии]
 
После обновления Ubuntu перестал запускаться просмотрщик PDF-файлов Evince, выдавая ошибку:

   (evince:5592): EggSMClient-WARNING **: Failed to connect to the session manager: 
   None of the authentication protocols specified are supported

Причина оказалась в использовании нестандартного пути к домашней директории,
указанной через символическую ссылку /home -> /home2. Как оказалось такая
манипуляция требует изменения настроек AppArrmor, который по умолчанию
активирован в последних релизах Ubuntu.

Чтобы Evince заработал с нестандартным /home2 необходимо указать данную
директорию в файле /etc/apparmor.d/tunables/home и перезапустить apparrmor:

   sudo /etc/init.d/apparmor reload

Похожие проблемы наблюдаются с переносом директории /usr/share и установкой
firefox в сборке Mozilla. В случае Firefox исправления нужно внести в файл
/etc/apparmor.d/usr.bin.firefox, а при переносе /usr/share потребуется поменять
с десяток разных файлов, определив в них упоминание /usr/share через поиск.
 
----* Настройка установки обновлений с исправлением проблем безопасности в RHEL/CentOS (доп. ссылка 1)   [комментарии]
 
Плагин yum-security позволяет использовать в yum команды list-security и
info-security, а также опции
"--security", "--cve", "--bz" и "--advisory" для фильтрации исправлений проблем
безопасности из общего массива обновлений.

Устанавливаем плагин:

   # yum install yum-security

Выводим список доступных обновлений, в которых непосредственно исправлены уязвимости:

   # yum list-security

Для вывода всех связанных с безопасностью обновлений (с учетом зависимостей):

   # yum --security check-update

Для вывода всех сообщений о проблемах, отмеченных в bugzilla:

   # yum list-security bugzillas

Вывод информации об исправлениях, связанных с уведомлением о наличии уязвимостей RHSA-2009:1148-1:

   # yum info-security RHSA-2009:1148-1

Вывод списка пакетов в которых устранены заданные ошибки отмеченные в Bugzilla, CVE и RHSA:

   # yum --bz 3595 --cve CVE-2009-1890 --advisory RHSA-2009:1148-1 info updates

Установка только обновлений, связанных с безопасностью:

   # yum update --security
 
----* Работа с web-клиентом альфабанка (ibank) в Linux (доп. ссылка 1)   Автор: Vitaly  [комментарии]
 
Краткое руководство для тех, кому в банке упорно твердят "наша система работает
только под windows".
На примере альфабанка для юридических лиц (с etoken) и Ubuntu 8.04.

Данное руководство подойдет для всех систем на основе ibank и систем, которые используют IAIK для 
"расширенной" связки между JAVA и PKCS11.

Итак, порядок действий.

1. Ставим драйверы etoken
-------------------------

Проблемы если и будут, то только с ними. Если драйверы заработают - все
остальное будет в порядке. Претензии - в Aladdin.

Берем на сайте http://aladdin.ru любую версию, которая больше нравится. 
Возможные проблемы: на самых последних сборках убунты (9.04) драйверы отказались работать. 
Когда выйдут версии под новое ядро - никому не известно. При желании, выкрутиться можно как-то так.

В аладдине проблему подтвердили, но ничем не обрадовали. Поэтому на тестовой
виртуальной машине для чистоты эксперимента использовал Ubuntu 8.04 LTS

(!!!) Перед тем как двигаться дальше, убедитесь, что у вас полностью работает
поддержка eToken от аладдина.
Если PKI Client не показывает содержимого ключа - продолжать нет смысла.

Теперь настраиваем то, чего не хватило альфабанку

Так как цифровые подписи там реализованы при участии Java, то любопытные могут
открыть java-консоль,
включить лог ошибок, и все посмотреть. После каждого шага можно пытаться
залогиниться в "центр сертификации",
и наблюдать за новыми ошибками.


2. Ставим Java
--------------

(!) Обратите внимание, что софт wrapper-а PKCS11, который используется в альфабанке, 
заточен под Java от Sun, поэтому ставить IceTea и прочие альтернативы НЕ НАДО. 
Наверное, можно попробовать пересобрать исходники под другую жабу, но я этого не пробовал.

Java ставится стандартным способом, из репозиториев, комментировать здесь нечего.


3. Ставим wrapper для IAIK (первая часть, pkcs11wrapper)
--------------------------------------------------------

IAIK - это библиотека для доступа к PKCS11 из Java-апплетов.

Любопытные могут прочитать тут (http://ideelabor.ee/opensource/wiki/IdKaardiTarkvara/DigiallkiriVeebisLinuxiga),
хотя файлы там старые (не поддерживают проброс нескольких функций, которые использует альфабанк). 
Свежую версию я скачал на сайте разработчиков http://jce.iaik.tugraz.at/download/ . 

На убунте я скопировал .so-библиотеку в каталог /usr/lib , чтобы при обновлении
java ничего не переставлять.

После этого в консоли пропали ошибки, что врапер не найден, и появилась ошибка,
что не удается инициализировать модуль eTpkcs11.


4. Создаем symlink на модуль pkcs11 для eToken.
-----------------------------------------------

Название модулей eToken различается под Windows и Линукс. Лечится просто.

  идем в каталог /usr/lib
  создаем там ссылку "eTpkcs11" на файл "libeTPkcs11.so" (это симлинк, в том же каталоге)

(!!!) Обратите внимание, что буквы Р в разном регистре. 

Теперь веб-клиент начинает понимать пин-код, и показывает сертификаты. Но при попытке залогиниться 
или авторизоваться, в джава-консоли выдается ошибка, что не найден какой-то метод в классе IAIK.


5. Ставим остатки IAIK (часть 2, java)
--------------------------------------

Берем jar-файл из архива, и копируем туда, где java его будет нормально видеть.
На убунте у меня получился такой путь:

   /usr/lib/jvm/java-6-sun/jre/lib/ext

По идее этого должно быть достаточно, но почему-то у меня в консоли полезли
ошибки вида "Access Denied".

Как временное решение - создал в домашней папке файл .java.policy и написал там

   grant {
      permission java.security.AllPermission;
   };

Вообще такие политики создавать категорически нельзя. Но я совершенно не
разбираюсь в линуксовой Java,
поэтому пока сделал так и пошел искать более опытных товарищей.
Естественно, можно перекрутить все конфигурационные файлы, но мне больше
нравится, когда работают пакеты,
поставленные из репозитория, без изменений. Как только кто-нибудь умный скажет
мне более правильный способ - сразу поменяю.

Все!

Теоретически etoken работает со свободными драйверами OpenCT/OpenSC, и
проприетарщину можно было бы выкинуть, но есть 2 проблемы:

1. У них другой формат хранения данных. Точнее, это драйверы aladdin не
соответствуют спецификации PKCS15 (хранение сертификатов).
На страничке разработчиков OpenCT написано, что Aladdin появился на рынке до
того, как возник стандарт PKCS15,
поэтому к проблеме надо относиться с пониманием. Правильный метод - записать
сертификат в ключ средствами OpenCT/OpenSC.

2. Альфабанк соглашается работать только с etoken. Получить сертификат в чистом виде, 
чтобы самостоятельно записать в ключ, у них нельзя. Они еще для полного счастья делают жесткую 
привязку серийного номера ключа к логину.

Поэтому в данном конкретном случае остается использовать проприетарные драйверы.
 
----* Обнаружение червя Conficker через пассивный анализ трафика (доп. ссылка 1)   [комментарии]
 
С конца 2008 года червь Conficker, поражающий Windows-клиентов, заразил
несколько миллионов машин в сети,
занимая первые позиции в рейтингах антивирусных компаний.

Для обнаружения активности червя на компьютерах локальной сети можно
рекомендовать несколько простых приемов:

1. Сниффинг сигнатуры червя через утилиту ngrep (http://ngrep.sourceforge.net/):


  ngrep -qd eth0 -W single -s 900 -X
   0xe8ffffffffc25f8d4f108031c4416681394d5375f538aec69da04f85ea4f84c84f84d84fc44f9ccc497365c4c4c42cedc4
   c4c494263c4f38923bd3574702c32cdcc4c4c4f71696964f08a203c5bcea953bb3c096969592963bf33b24699592514f8ff8
   4f88cfbcc70ff73249d077c795e44fd6c717cbc404cb7b040504c3f6c68644fec4b131ff01b0c282ffb5dcb61f4f95e0c717
   cb73d0b64f85d8c7074fc054c7079a9d07a4664eb2e244680cb1b6a8a9abaac45de7991dacb0b0b4feebeb
    'tcp port 445 and dst net 192.168.0.0/16'

конструкцию нужно переписать одной строкой


2. Сканирование компьютеров с использованием готовой маски из комплекта
последней версии nmap ( nmap-4.85BETA6):

   nmap -PN -T4 -p139,445 -n -v --script=smb-check-vulns --script-args safe=1 192.168.1.0/24

или оптимизировав запрос для сканирования сети большого объема:

   nmap -sC -PN -d -p445 -n -T4 --min-hostgroup 256 \
   --min-parallelism 64 --script=smb-check-vulns \
   --script-args=safe=1 192.168.0.0/16

3. Проверить зараженность отдельной машины можно через специально подготовленный Python скрипт.

   wget http://iv.cs.uni-bonn.de/uploads/media/scs.zip
   unzip scs.zip
   ./scs.py 192.168.1.100
 
----* Аутентификация при помощи Bluetooth телефона или USB Flash в Debian/Ubuntu Linux (доп. ссылка 1) (доп. ссылка 2) (доп. ссылка 3) (доп. ссылка 4)   [комментарии]
 
В качестве ключа для авторизации можно использовать MAC адрес телефона с Bluetooth интерфейсом.
Для избежания перехвата MAC-адреса, Bluetooth адаптер телефона должен работать
только в пассивном режиме.
Тем не менее метод можно использовать только в ситуациях не предъявляющих
серьезных требований к безопасности
(например, для входа на гостевую машину или только для выполнения sudo).

Если bluetooth система не настроена, устанавливаем пакеты bluetooth, bluez-utils и libbluetooth2.
Выполнив команду hcitool scan определяем адрес нужного телефона, переведя
телефон в режим достижимости:

   hcitool scan
   Scanning...
   00:0E:08:BA:14:04 Moto

Ставим пакет libpam-blue, если в вашем дистрибутиве его нет - 
загружаем исходные тексты с http://pam.0xdef.net/ и компилируем.

Создаем файл конфигурации /etc/security/bluesscan.conf

    general {
       timeout = 10;
    }
    mylogin = {
       name = Moto;
       bluemac = 00:0E:08:BA:14:04;
    } 

где mylogin имя пользователя для которого будет осуществлен автоматический вход.

В /etc/pam.d/common-auth добавляем строку

   auth sufficient pam_blue.so

Добавив эту строку в /etc/pam.d/sudo можно добиться выполнения sudo без пароля
при наличии телефона под рукой.

Настройка аутентификации через USB Flash производится аналогично, 
только вместо PAM модуля pam_blue.so используется pam_usb.so, доступный из пакета libpam_usb.

В /etc/pam.d/common-auth добавляем:

   auth sufficient pam_usb.so

Далее подключаем USB Flash и создаем ключи для пользователя mylogin:

   pamusb-conf --add-device myusbflash
   pamusb-conf --add-user mylogin

Также можно вручную отредактировать файл конфигурации /etc/pamusb.conf.

Проверяем:

   pamusb-check mylogin
   ...
   Access granted.

Инструкцию по аутентификации с использованием датчика отпечатков пальцев можно найти на странице 
http://www.opennet.dev/tips/info/1586.shtml
 
----* Как выделить файлы из перехваченной tcpdump-ом сессии   [комментарии]
 
Утилита chaosreader (http://chaosreader.sourceforge.net) позволяет выделить
пользовательские данные из лога tcpdump.
Например, можно сохранить переданные по FTP файлы, картинки запрошенные по
HTTP, сообщения электронной почты переданные по SMTP,
ключи переданные в SSH сессии.
Дополнительно поддерживается выделение данные из дампа трафика различных туннелей, 802.11b и PPPoE.

Передав утилите chaosreader на вход накопленный дамп, на выходе получим html
файл с анализом пересылок
и ссылками на встретившиеся в сессии файлы.

Собираем лог:

   tcpdump -s0 -w output1

Анализируем лог и выделяем все встретившиеся файлы:

   chaosreader -ve output1 

Анализируем только ftp и telnet трафик:

   chaosreader -p 20,21,23 output1 

Запускаем в режиме сниффера, сбрасывающего накопленные сессии 5 раз по 2 минуты каждая:

  chaosreader -S 2,5

В комплект входит утилита replay, позволяющая вторично проиграть сценарий
перехваченного telnet, rlogin, IRC, X11 или VNC сеансов.


Другие похожие утилиты:

* pcapsipdump (http://sourceforge.net/projects/psipdump) -  выделение из потока SIP и RTP данных 
для последующего прослушивания, каждая SIP сессия сохраняется в отдельный файл.

* smbsniff (http://www.hsc.fr/ressources/outils/smbsniff) - позволяет сохранять
переданные по SMB/CIFS
протоколу файлы, присутствующие в перехваченном трафике;

* Tcpreplay(http://tcpreplay.synfin.net) - набор утилит для повторного инициирования сессий 
на основе перехваченного трафика.

* Wireshark (http://www.wireshark.org/) - универсальный сниффер и комплект вспомогательных утилит,
позволяет извлекать данные различных типов из перехваченных потоков трафика
 
----* Как разрешить доступ к точке монтирования для приложения контролируемого SELinux (доп. ссылка 1)   [обсудить]
 
Имеется CentOS с активным  SELinux. 
Требуется обеспечить возможность доступа Apache к примонтированному локально iso-образу, USB Flash 
или диску, содержащему файловую систему без поддержки SELinux.

Решение: при монтировании необходимо явно определить политику доступа через опцию "context=".
По умолчанию используется "context=system_u:object_r:removable_t".
Для apache нужно монтировать так:

   mount -o loop,context=system_u:object_r:httpd_sys_content_t /path/to/image.iso /var/www/html
 
----* Изменение метода хэширования паролей в Red Hat подобных дистрибутивах (доп. ссылка 1)   [комментарии]
 
В будущих версиях RHEL и Fedora Linux появится возможность
 использования для хэширования паролей алгоритмов SHA-256 и SHA-512 

В Kickstart режиме:

DES

   authconfig --enableshadow --passalgo=descrypt

MD5

   authconfig --enableshadow --enablemd5
или
   authconfig --enableshadow --passalgo=md5

SHA-256

   authconfig --enableshadow --passalgo=sha256

SHA-512

   authconfig --enableshadow --passalgo=sha512

Тип хэша также можно задать через /etc/logis.desf, присвоив переменной
 ENCRYPT_METHOD значение DES, MD5, SHA256 или SHA512
 
----* Настройка аутентификации по отпечаткам пальцев в Ubuntu Linux   [комментарии]
 
Устанавливаем пакеты необходимые для сборки системы fprint:
  aptitude install libpam0g-dev libusb-dev libmagick9-dev libglib2.0-dev libssl-dev
  aptitude install libgtk2.0-dev libx11-dev libxv-dev # если будет сборка с поддержкой x11

Загружаем libfprint и pam_fprint с сайта http://www.reactivated.net/fprint 
Собираем стандартно через: 
   ./configure
   make
   make install

Или пересобираем готовые Debian пакеты:  
---
   Качаем .dsc, tar.gz и diff.gz со страниц
   http://packages.debian.org/experimental/libfprint0
   http://packages.debian.org/experimental/libpam-fprint

   Устанавливаем доп. пакеты необходимые для сборки:
   aptitude install fakeroot autotools-dev debhelper dpkg-dev 
   
   dpkg-source -x libfprint_0.0.5-2.dsc
   cd libfprint-0.0.5
   dpkg-buildpackage -rfakeroot 

   Пакет libpam-fprint создается по аналогии
---

Генерируем слепок отпечатка указательного пальца 
(запускаем под логином для которого сохраняем отпечаток):
   pam_fprint_enroll --enroll-finger 7

Для опциональной аутентификации по отпечатку (возможность ввести пароль остается), 
в /etc/pam.d/common-auth первой строкой ставим:
   auth   sufficient      pam_fprint.so

Если пускать в систему нужно только после сверки отпечатка, "sufficient" заменяем на "required".

PS. В Gentoo Linux добавляем в /etc/pam.d/system-auth перед строкой c pam_unix.so
 
----* Использование login.access в FreeBSD 5.x и 6.x   Автор: 135all  [обсудить]
 
В FreBSD есть прекрасная возможность разрешать логинится конкретным пользователям 
только с определённых терминалов или адресов. Делается это посредством модуля pam_acct_mgmt. 

Для этого редактируем файл /etc/login.access:

   -:root:ALL #запрещаем любые логины root
   -:ALL:ttyv0 # первая консоль только для логов
   +:dm:ttyv1 ttyv2 ttyv3 ttyv4 ttyv5 ttyv6 ttyv7 ttyv8 # доступ с консоли
   +:dm:10.1.1.1 192.168.6.100 # доступ по сети(тут указывать либо ip, либо 
        # доменное имя. Для ssh рекомендую UseDNS no в /etc/ssh/sshd_config)
   -:ALL:ALL # всё остальное запрещено

ВАЖНО! начиная с версии 5.2 su стал проверять "target user" по login.access, те
при таких настройках
можно будет залогинится, но su не будет работать - pam_login_access: 
   pam_sm_acct_mgmt: root is not allowed to log in on /dev/ttyp3 su: Sorry. 

Для исправления надо редактировать /etc/pam.d/su:

   account
   #account                include         system #закомментировать
   account         required        pam_unix.so # добавить
 
----* Как найти все SUID программы на машине   [обсудить]
 
Все SUID и SGID программы:
find / \( -perm -04000 -o -perm -02000 \) -exec ls -ald {} \;
Только SUID ROOT:
find /sbin \( -perm -04000 -a -user 0 \) -exec ls -ald {} \;
 
----* Борьба с троллингом на opennet.ru при помощи uBlock Origin   Автор: уля  [комментарии]
 
В последнее время на портале opennet.ru участились случаи троллинга и
провокационных постов в новостях. Читатели, не желающие видеть комментарии
и/или новости от какого-либо конкретного пользователя могут скрыть их при
помощи пользовательских фильтров uBlock Origin. Это позволит сэкономить время и
нервы при посещении ресурса.

Правило для вырезания тела новости через определение автора по ссылке на профиль пользователя:

   www.opennet.ru##table.ttxt2:nth-of-type(2):has(a[href="ссылка_на_профиль"])

Скрытие комментариев посредством удаления 4 родительских элементов (блок
комментария) перед ссылкой на профиль:

   www.opennet.ru##a[href="ссылка_на_профиль"]:nth-ancestor(4)


Пример

Например, для скрытия новостей и комментариев пользователя QwertyReg правила будут выглядеть так:

   ! Скрыть новости от QwertyReg
   www.opennet.ru##table.ttxt2:nth-of-type(2):has(a[href="/~QwertyReg"])

   ! Скрыть комментарии от QwertyReg
   www.opennet.ru##a[href="/~QwertyReg"]:nth-ancestor(4)


Дополнение: Для рекурсивного скрытия комментариев можно использовать штатную функцию
игнорирования участников.
 
----* Возможные проблемы с настройками пакета tor в Debian по умолчанию (доп. ссылка 1)   Автор: Аноним  [комментарии]
 
Пользователям пакетов, зависимых  от пакета tor в Debian, следует проявить
осторожность. Файл конфигурации, идущий с пакетом tor, закомментирован почти
полностью, включая места, запрещающие узлу работать в режиме выходного узла
Tor. Настройки по умолчанию ( ExitRelay = "auto") подразумевают работу как
выходного узла при определённых условиях (если активна одна из опций -
ExitPolicy, ReducedExitPolicy или IPv6Exit).

Проблему усугубляет то, что от пакета tor зависит apt-transport-tor, что может
привести к ситуации, когда пользователь не разбираясь установил пакет для
большей безопасности, а получил доступ всех подряд в свою внутреннюю сеть и
перспективу претензий со стороны правоохранительных органов, как в деле
Дмитрия Богатова.

Дополнение: По умолчанию активация tor не подтверждена, по крайней мере в
Debian Stable, если действия пользователя не привели к изменению настроек
ExitPolicy, ReducedExitPolicy и IPv6Exit.
 

   Ограничение доступа и безопасность Apache:

   ipfw, IP-Filter:

   iptables, ipchains:

   Безопасность почтовой подсистемы:

   Увеличение безопасности FreeBSD:

   Увеличение безопасности Linux:

   SSH

----* Проброс доступа к SSH через HTTPS (доп. ссылка 1)   [комментарии]
 
Для организации подключения к SSH-серверу из окружений, в которых заблокирован
любой трафик, кроме HTTP/HTTPS, можно настроить проброс к SSH на основе
внешнего HTTP-прокси.

На локальной системе, из которой производится подключение по SSH, добавляем в
файл конфигурации ~/.ssh/config настройку для проброса доступа к SSH-сервру с
именем "ssh-server" через обращение к хосту "ssh-via-https" утилитой ssh:


.ssh/config

   Host ssh-via-https
        ProxyCommand ~/.ssh/https-tunnel.bash
        # уменьшаем интервал проверочных запросов для поддержания соедиения, 
        # так как некоторые межсетевые экраны агрессивно закрывают неактивные соединения.
        ServerAliveInterval 30

Создаём скрипт ~/.ssh/https-tunnel.bash, в котором симулируем использование
прокси-метода CONNECT при подключении к HTTPS-серверу "https-server" через
утилиту socat, которая не поддерживает данный метод.

   #!/usr/bin/env bash
   { printf "CONNECT ssh-server:22 HTTP/1.0\r\n\r\n"; cat; } | socat - SSL:https-server:443

На стороне внешнего HTTP-сервера "https-server" в конфигурации Apache httpd
включаем модуль proxy_connect_module и разрешаем перенаправление запросов на 22
сетевой порт SSH-сервера "ssh-server".

/etc/httpd/httpd.conf

   LoadModule proxy_connect_module .../modules/mod_proxy_connect.so
   # ...
   AllowCONNECT 22
   <Proxy *>
       Order deny,allow
       Deny from all
   </Proxy>
   <Proxy ssh-server>
       Order deny,allow
       Allow from all
   </Proxy>

Подключаемся к SSH-серверу "ssh-server" командой:

   ssh ssh-via-https
 
----* Использование SSH поверх UNIX-сокета вместо sudo (доп. ссылка 1)   [комментарии]
 
Тимоти Равье (Timothee Ravier) из компании Red Hat, мэйнтейнер проектов Fedora
Silverblue и Fedora Kinoite, предложил заслуживающий внимания способ ухода
от применения утилиты sudo, использующей  suid-бит для повышения привилегий.
Вместо sudo для выполнения обычным пользователем команд с правами root
предлагается задействовать утилиту ssh с локальным соединением к той же системе
через UNIX-сокет.

Проверка полномочий осуществляется на основе SSH-ключей. Для ограничения доступ
дополнительно может быть задействовано подтверждение полномочий при помощи
USB-токена (например, Yubikey). Использование ssh вместо sudo позволяет
избавиться от suid-программ в системе и организовать  выполнение
привилегированных команд в хост-окружении дистрибутивов, использующих
контейнерную изоляцию компонентов, таких как Fedora Silverblue, Fedora Kinoite,
Fedora Sericea и Fedora Onyx.

Настраиваем серверные компоненты OpenSSH для доступа через локальный Unix-сокет
(будет запускаться отдельный экземпляр sshd со своим файлом конфигурации):

/etc/systemd/system/sshd-unix.socket:

   [Unit]
   Description=OpenSSH Server Unix Socket
   Documentation=man:sshd(8) man:sshd_config(5)

   [Socket]
   ListenStream=/run/sshd.sock
   Accept=yes

   [Install]
   WantedBy=sockets.target



/etc/systemd/system/sshd-unix@.service:

   [Unit]
   Description=OpenSSH per-connection server daemon (Unix socket)
   Documentation=man:sshd(8) man:sshd_config(5)
   Wants=sshd-keygen.target
   After=sshd-keygen.target

   [Service]
   ExecStart=-/usr/sbin/sshd -i -f /etc/ssh/sshd_config_unix
   StandardInput=socket


/etc/ssh/sshd_config_unix:

   # Оставляет только аутентификацию по ключам
   PermitRootLogin prohibit-password
   PasswordAuthentication no
   PermitEmptyPasswords no
   GSSAPIAuthentication no

   # ограничиваем доступ выбранным пользователям
   AllowUsers root adminusername

   # Оставляем только использование .ssh/authorized_keys (без .ssh/authorized_keys2
   AuthorizedKeysFile .ssh/authorized_keys

   # включаем sftp
   Subsystem sftp /usr/libexec/openssh/sftp-server


Активируем и запускаем юнит systemd:

   sudo systemctl daemon-reload
   sudo systemctl enable --now sshd-unix.socket


Добавляем свой SSH-ключ в /root/.ssh/authorized_keys


Настраиваем работу SSH-клиента.

Устанавливаем утилиту socat:

   sudo dnf install socat

Дополняем /.ssh/config, указав socat в качестве прокси для доступа через UNIX-сокет:

   Host host.local
       User root
       # Используем /run/host/run вместо /run для работы из контейнеров
       ProxyCommand socat - UNIX-CLIENT:/run/host/run/sshd.sock

       # Путь к SSH-ключу
       IdentityFile ~/.ssh/keys/localroot

       # Включаем поддержку TTY для интерактивной оболочки
       RequestTTY yes

       # Убираем лишний вывод
       LogLevel QUIET

В текущем виде пользователь adminusername теперь сможет выполнить команды с
правами root без ввода пароля. Проверяем работу:

   $ ssh host.local
   [root ~]#


Создаём в bash псевдоним sudohost для запуска "ssh host.local" по аналогии с sudo:

   sudohost() {
       if [[ ${#} -eq 0 ]]; then
           ssh host.local "cd \"${PWD}\"; exec \"${SHELL}\" --login"
       else
           ssh host.local "cd \"${PWD}\"; exec \"${@}\""
       fi 
   }

Проверяем:

   $ sudohost id
   uid=0(root) gid=0(root) groups=0(root) 


Добавляем проверку полномочий и включаем двухфакторную аутентификацию,
допускающую доступ к root только при вставке USB-токена Yubikey.

Проверяем, какие алгоритмы поддерживает  имеющийся Yubikey:

   lsusb -v 2>/dev/null | grep -A2 Yubico | grep "bcdDevice" | awk '{print $2}'

Если выведено 5.2.3 или большее значение, используем ed25519-sk при генерации
ключей, иначе - ecdsa-sk:

   ssh-keygen -t ed25519-sk
или
   ssh-keygen -t ecdsa-sk

Добавляет открытый ключ в /root/.ssh/authorized_keys

Добавляем привязку к типу ключа в конфигурацию sshd:

/etc/ssh/sshd_config_unix:

   PubkeyAcceptedKeyTypes sk-ecdsa-sha2-nistp256@openssh.com,sk-ssh-ed25519@openssh.com

Ограничиваем доступ к Unix-сокету только пользователя, которому можно повышать
привилегии (в нашем примере - adminusername). В
/etc/systemd/system/sshd-unix.socket добавляем:

   [Socket]
   ...
   SocketUser=adminusername
   SocketGroup=adminusername
   SocketMode=0660
 
----* Преобразование закрытого ключа PuTTY для использования в OpenSSH  (доп. ссылка 1)   [комментарии]
 
Для преобразования можно использовать утилиту puttygen из пакета putty-tools или putty.

Debian/Ubuntu:
  
   sudo apt-get install putty-tools

Fedora:

   sudo yum install putty


   puttygen putty.ppk -O private-openssh -o ~/.ssh/id_putty
   puttygen putty.ppk -O public-openssh  -o ~/.ssh/id_putty.pub
   chmod 0600 ~/.ssh/id_putty
   chmod 0644 ~/.ssh/id_putty.pub


Для подключения к хосту с закрытым ключом, преобразованным из ключа PuTTY:

   ssh user@host -i ~/.ssh/id_putty
 
----* Использование SSH-ключей в Gitlab CI   Автор: Ilya  [комментарии]
 
Многие хотят использовать ssh ключи в своих CI/CD (не одобряю), но давайте делать это правильно:

   before_script:
    - '[[ ! -d /root/.ssh ]] && mkdir /root/.ssh && chmod 700 /root/.ssh'
    - '[[ -f /.dockerenv ]] && echo -e "Host *\\n\\tStrictHostKeyChecking no\\n\\n" > ~/.ssh/config'
    - 'which ssh-agent || (yum install openssh-clients -y; yum clean all -y )'
    - eval $(ssh-agent -s)
    - ssh-add <(echo "$SSH_PRIVATE_KEY")
    - mkdir -p ~/.ssh

В $SSH_PRIVATE_KEY устанавливаем "protected" переменную в интерфейсе самого
Gitlab (repo->settings->ci/cd-> vars )

Данный сниппет рассчитан на CentOS, но легко адаптируется по любую ОС, работает
в докер окружении (см. строку #2). При таком подходе больше нет нужды помещать
id_rsa в репозитории (ему там и не место).
 
----* Генерация конфигурации клиента OpenSSH из inventory.ini в Ansible   Автор: Ilya  [комментарии]
 
Часто на работе приходится разыскивать серверы, грепать из inventory.ini. Но
почему бы Ansible не позаботится о нас. Настраиваем генерацию ~/.ssh/config из inventory.ini:

   cat ssh-config.yml:
   ---
   - name: Generate ssh client configuration from ansible inventory
     hosts: localhost
     connection: local
     gather_facts: no
     vars:
       title: "EasyConfig by Ansible"
       ssh_config_path: ssh_config.txt
     tasks:
       - name: ensure config for each host of inventory exist
         template: src="ssh_config.j2" dest="{{ ssh_config_path }}"
         when: ssh_config_path != ""


   cat ssh-config.j2 :
      #### {{ title }} Begin ####
   
   {% for host in groups.all | sort() | list %}
   
   {% if host != "localitem" and host != "127.0.0.1" and host != "localhost" %}
   Host {{hostvars[host].inventory_hostname}}
   {% if hostvars[host].ansible_host is defined and hostvars[host].ansible_host != "" %}  HostName {{hostvars[host].ansible_host}}
   {% else %}  HostName {{hostvars[host].inventory_hostname}}
   {% endif %}
   {% if hostvars[host].ansible_ssh_port is defined %}  Port {{hostvars[host].ansible_ssh_port}}
   {% endif %}
   {% endif %}
   {% endfor %}
   
   # Defaults
   Host *
       User root
       Port 22

   
   #### {{ title }} End ####


Получившийся ssh_config.txt - внимательно осматриваем и добавляем (или нет)  к
своему ~/.ssh/config.

Как профит имеем автокомплит по серверам (можно добавить префикс), не тратим
время на grep hostname Passwords_Hosts.txt можем прямо из Ansible управлять процессом.
 
----* Еscape-последовательности в сеансе OpenSSH   [комментарии]
 
В сеансе удалённого входа через OpenSSH можно использовать
escape-последовательность "~" (действует только в начале новой строки, в
которой не было ввода, поэтому перед "~" лучше нажать Enter) для запуска ряда
полезных команд. Например, можно набрать "~C", а затем ввести "-D 1080" для
запуска SOCKS-прокси или "-L 80:localhost:8000" для проброса сетевого порта без
запуска отдельного сеанса.

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

  ~.  - принудительное завершение сеанса (например, при зависании соединения);
  ~B  - отправка команды BREAK;
  ~C  - открытие командной строки для динамической установки некоторых опций командной строки. 
        Поддерживается установка опций  "-L", "-R", "-D" (разные виды проброса) и "-KR" (отмена проброса);
  ~R  - инициирование обновления ключей;
  ~ Ctrl+Z - приостановка сеанса с возвращением в shell, для возврата следует выполнить команду fg;
  ~#  - вывод списка перенаправленных соединений;
  ~&  - завершить работу в фоне (при ожидании завершения соединений);
  ~?  - вывод подсказки по командам;
  ~~  - отображение escape-символа.
 
----* Настройка SSH для использования наиболее защищённых алгоритмов шифрования (доп. ссылка 1)   [комментарии]
 
В свете появления сведений об организации АНБ атак, направленных на
получение контроля над SSH-соединениями, подготовлено руководство с
рекомендациями по усилению защищённости SSH. АНБ может получить контроль за
SSH-соединением  в случае использования уязвимых методов шифрования или в
результате захвата приватных ключей. Ниже представлены советы по отключению
потенциально проблемных алгоритмов и усилению защиты.


Обмен ключами.

Применяемые в SSH методы обмена ключей  DH (Diffie-Hellman) и ECDH (Elliptic
Curve Diffie-Hellman) можно считать безопасными. Из 8 поддерживаемых в SSH
протоколов обмена ключами вызывают подозрения три,  основанные на рекомендациях
NIST: ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521. Не
заслуживающими полного доверия также можно считать протоколы, использующие
потенциально проблемный SHA1. Протоколы curve25519-sha256 и diffie-hellman-group-exchange-sha256
 пока не вызывают сомнений в безопасности.

Для использования только заслуживающих доверия протоколов обмена ключами в
/etc/ssh/sshd_config  для сервера следует указать:

    KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256

Аналогичные настройки для клиента, в /etc/ssh/ssh_config:

   Host *
      KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256

В /etc/ssh/moduli можно указать (или удалить строки с размером ключа, менее 2048):

   ssh-keygen -G /tmp/moduli -b 4096
   ssh-keygen -T /etc/ssh/moduli -f /tmp/moduli


Аутентификация.

В SSH поддерживается четыре алгоритма аутентификации по открытым ключам: DSA,
ECDSA,  Ed25519 и RSA. ECDSA завязан на технологиях NIST и должен быть
отключен. К сожалению, если просто удалить ключ ECDSA, он будет повторно
сгенерирован, поэтому можно воспользоваться обходным путём с создать заведомо
нерабочую символическую ссылку, которая помешает сгенерировать и использовать ключ:

   cd /etc/ssh
   rm ssh_host_ecdsa_key*
   rm ssh_host_key*
   ln -s ssh_host_ecdsa_key ssh_host_ecdsa_key
   ln -s ssh_host_key ssh_host_key

Так как размер ключей DSA  не может превышать 1024, его тоже следует отключить тем же способом:

   cd /etc/ssh
   rm ssh_host_dsa_key*
   ln -s ssh_host_dsa_key ssh_host_dsa_key

Далее, следует позаботиться о RSA, сгенерировав ключ большего размера:

   cd /etc/ssh
   rm ssh_host_rsa_key*
   ssh-keygen -t rsa -b 4096 -f ssh_host_rsa_key < /dev/null

Для создания клиентских ключей лучше использовать команды:

   ssh-keygen -t ed25519
   ssh-keygen -t rsa -b 4096


Симметричные шифры.

Из 15 поддерживаемых в SSH алгоритмов симметричного шифрования, используемых
для организации защиты установленного канала связи, безопасными можно считать
chacha20-poly1305, aes*-ctr и aes*-gcm. Шифры 3des-cbc и arcfour потенциально
уязвимы в силу использования DES и RC4, cast128-cbc применяет слишком короткий
размер блока (64 бит).

В итоге, в /etc/ssh/sshd_config рекомендуется добавить:

   Ciphers aes256-gcm@openssh.com,aes128-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr

В /etc/ssh/ssh_config:

   Host *
      Ciphers aes256-gcm@openssh.com,aes128-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr

Код аутентичности сообщения (MAC).

Для шифров в режиме  CTR для гарантирования  целостности передаваемых блоков
доверия заслуживает только метод Encrypt-then-MAC ("*-etm", MAC добавляется  к
уже зашифрованному блоку). Методы MAC-then-encrypt и Encrypt-and-MAC
потенциально подвержены атакам. Из 18 доступных в SSH алгоритмов MAC  сразу
следует отбросить основанные на хэшах  MD5 и SHA1, не стойких к выявлению
коллизий, а также алгоритмы использующие размеры ключей менее 128 бит и размеры
тегов менее 256 бит. В итоге, наиболее безопасными MAC  можно считать
hmac-sha2-512-etm и hmac-sha2-256-etm.

В /etc/ssh/sshd_config:

   MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com

В /etc/ssh/ssh_config:

   # Для GitHub в качестве исключения добавляем mac-sha2-512, так как он не поддерживает Encrypt-then-MAC.
   Host github.com
       MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512

   Host *
      MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com


Защита от утечки ключей.

Наиболее простым способом получения контроля за SSH-соединением является захват
ключей на стороне клиента или сервера. Рекомендации сводятся к соблюдению
типовых правил поддержания безопасности системы: оперативная установка
обновлений, установка программ только из надёжных источников, установка только
действительно необходимых программ и сервисов, использование программ для
которых доступны исходные тексты, включение дополнительных механизмов защиты
(Grsecurity, сборка с флагом -fstack-protector).

Для защиты ключей следует выбрать надёжный пароль доступа к клиентским файлам
ключей. При формировании ключа для увеличения числа итераций хэширования можно
использовать опцию "ssh-keygen -o -a число", что  усложнит подбор пароля. Также
можно сохранить ключи только на внешнем носителе, подключая его только во время
соединения по SSH.

Защита от анализа транзитного трафика.

SSH-сервер можно настроить в виде скрытого сервиса Tor, что скроет IP, а также
добавит дополнительный слой шифрования и аутентификации.

Для приема соединений только через скрытый сервис Tor можно использовать следующие настройки:

В /etc/ssh/sshd_config (для приема соединений из LAN следует вместо привязки к
127.0.0.1 использовать для ограничения доступа межетевой экран):

   ListenAddress 127.0.0.1:22

В /etc/tor/torrc добавим:

   HiddenServiceDir /var/lib/tor/hidden_service/ssh
   HiddenServicePort 22 127.0.0.1:22

Имя скрытого хоста для подключения можно найти в файле /var/lib/tor/hidden_service/ssh/hostname. 

Для настройки подключения клиента к скрытому сервису Tor в  /etc/ssh/ssh_config можно добавить:

   Host *.onion
       ProxyCommand socat - SOCKS4A:localhost:%h:%p,socksport=9050
 
----* Применение двухфакторной аутентификации для SSH и GDM средствами Google Authenticator (доп. ссылка 1) (доп. ссылка 2) (доп. ссылка 3)   [комментарии]
 
При применении двухфакторной аутентификации, кроме традиционного логина/пароля
или ключа требуется ввести код подтверждения, получаемый с устройства, заведомо
принадлежащего владельцу аккаунта. Наиболее простым способом является
использование открытого проекта  Google Authenticator, который предоставляет
мобильное приложение для генерации одноразовых паролей (TOTP) и PAM-модуль для
установки на стороне сервера.

На сервере устанавливаем PAM-модуль и утилиту настройки, которые во многих
дистрибутивах содержится в пакете google-authenticator:

   sudo yum install google-authenticator

Устанавливаем на мобильный телефон приложение Google Authenticator, которое
доступно для Android, iOS, Firefox OS и других платформ.

На сервере под учётной записью пользователя, для которого хотим включить
двухфакторную аутентификацию, запускаем команду:

    google-authenticator

которая отобразит картинку с QRcode, которую необходимо снять через камеру
телефона из мобильного приложения Google Authenticator, а также покажет коды
экстренного восстановления, которые позволят восстановить доступ в случае
потери смартфона.

Для включения  двухфакторной аутентификации в SSH на сервере активируем
PAM-модуль, добавив в /etc/pam.d/sshd строку:
 
   auth required pam_google_authenticator.so
 
В конфигурации OpenSSH /etc/ssh/sshd_config активируем опцию ChallengeResponseAuthentication:
  
   ChallengeResponseAuthentication yes

Не забываем перезапустить sshd:

   sudo service sshd restart

Теперь при попытке входа по SSH потребуется ввести не только пароль, но и
действующий несколько секунд одноразовый код, который следует получить из
мобильного приложения.

   Verification code: ********
   Password: ********



Кроме SSH, на рабочей станции можно добавить поддержку двухфакторной
аутентификации в экранный менеджер GDM, для этого добавим в файл
/etc/pam.d/gdm-password строку:
 
   auth required pam_google_authenticator.so

При следующем входе, кроме пароля GDM  запросит одноразовый код подтверждения.
 
----* Двухфакторная аутентификация SSH с использованием YubiKey (доп. ссылка 1)   Автор: Dvenum  [комментарии]
 
Все началось с того, что я приобрел YubiKey и захотел использовать его для
двухфакторной аутентификации SSH. Я также хотел иметь возможность восстановить
доступ к серверу на случай, если потеряю ключ. Информация о том, как это
сделать, слишком разрознена, поэтому я написал собственное руководство.

Вещи, которые необходимо знать:

* HOTP -- это алгоритм генерации одноразового пароля на основе счетчика.
Счетчик меняется каждый раз, когда генерируется новый пароль.
* TOTP -- алгоритм генерации пароля в зависимости от таймера, регулярно
генерируется новый пароль. (30 секунд в этом случае).

В результате, вы входите через SSH, видите запрос пароля и вводите пароль,
предоставленный OTP, системой одноразовых паролей (one-time password) от YubiKey.

Для аварийного доступа я настроил возможность аутентификации с помощью
Android-приложения Google Authenticator. Я настраивал все на Debian Wheezy
сервере, но это должно работать и для других похожих систем.

Вам необходимо установить libpam-oath на сервере (>=1.12.4-1 или вы не сможете
использовать аварийный вход).
На вашем компьютере необходимо установить yubikey-personalization-gui, oathtool
и libmime-base32-perl.

Когда вы установите необходимые программы и библиотеки, то прежде, чем
приступать к настройке, убедитесь, что у вас открыт дополнительный терминал с
правами root, чтобы можно было исправить возможные ошибки.

Ключ ниже указан просто для примера, вам необходимо подставить свой.

Настройка YubiKey.

Для начала, используем yubikey-personalisation-gui, чтобы настроить YubiKey и
сгенерировать ключ. Укажите OATH-HOTP режим, отключите token идентификацию и
скопируйте ключ куда-нибудь, он понадобится для настройки сервера. Не забудьте
сохранить настройки в YubiKey.

Создайте файл /etc/users.oath на сервере с содержанием:

   HOTP robin - 8a54ac40689f0bb99f306fdf186b0ef6bd153429

где robin это имя пользователя, использующего ключ, а большая шестнадцатиричная
строка это ключ без пробелов, который вы сгенерировали ранее.

Установите возможность читать файл только для root:

   # chmod 600 /etc/users.oath

Измените /etc/pam.d/sshd таким образом, чтобы строка

   @include common-auth

была раскомментирована, а после нее добавьте следующее:

   auth required pam_unix.so nullok_secure

   # OATH OTP
   auth required pam_oath.so usersfile=/etc/users.oath window=20

window=20 указывает, как много раз может быть нажата кнопка на YubiKey перед
входом. Иными словами, как далеко в последовательности OTP модуль будет искать совпадение.

Измените sshd_config, чтобы он разрешал вызов-ответ (Challenge-Response) аутентификацию.

   sed -i.bak -E -e 's/(ChallengeResponseAuthentication) no/\\1 yes/' /etc/ssh/sshd_config

Вы можете проверить последовательность следующим образом:

   $ oathtool -w10 8a54ac40689f0bb99f306fdf186b0ef6bd153429
   333518
   886962
   ...

Если вы нажмете кнопку на YubiKey несколько раз, вы дожны увидеть точно такую
же последовательность.

Перезапустите ssh демон и все должно работать. Вам нужно ввести пароль, вы
нажимаете на кнопку YubiKey.

Настройка Google Authenticator

Это будет аварийным входом на случай, если вы потеряете ключ. Используем здесь
повременной счетчик TOTP вместо счетчика на основе последовательности.

Для начала сгенерируйте случайный десятибайтовый ключ (20 символов в шестнадцатиричном виде):

   $ head -c 1024 /dev/urandom | openssl sha1 | tail -c 21 
   2c2d309a7a92e117df5a

Добавьте строку в /etc/users.oath:

   HOTP/T30 robin - 2c2d309a7a92e117df5a

T30 означает, что используется повременной алгоритм с 30-и секундной ротацией.

Перед тем, как добавить этот же ключ в android приложение, мы должны представить его в base32 виде:

   $ perl -e 'use MIME::Base32 qw( RFC ); print  lc(MIME::Base32::encode(pack("H*","2c2d309a7a92e117df5a")))."\\n";'
   fqwtbgt2slqrpx22

Эта команда на perl из шестнадцатиричного ключа сначала получает двоичный,
который потом преобразовывает в base32.
Проверить, что все работает, можно так:

   $ oathtool --totp -w10 2c2d309a7a92e117df5a
   125557
   804612
   ...

Последовательность должна совпадать с той, которую отдает android приложение.
Поскольку алгоритм генерации основывается на времени, то разница времени на
устройствах должна не превышать пары секунд.

Теперь вы можете войти на сервер через повременной ключ, сгенерированный
приложением или с помощью пароля, сгенерированным нажатием на кнопку YubiKey.

Примечания

Когда вы залогиньтесь, файл users.oath будет изменен, в него будет записано
новое значение счетчика и время. Убедитесь, что файл не открыт в текстовом редакторе.

Если кто-нибудь нажмет кнопку YubiKey много раз (больше двадцати для этого
примера), то ключ рассинхронизируется с сервером и вам придется сбросить его,
сгенерировав новый и заменив старый в users.oath.

Есть еще libpam-google-authenticator, который ведет себя похожим образом, но
недоступен для Debian Wheezy.

Если у вас много сервереров и вы хотите использовать один YubiKey для всех, то
вам потребуется что-нибудь вроде центрального сервера аутентификации, чтобы
избежать рассинхронизации ключей.
 
----* Автоматизация запуска PuTTY и XMing   Автор: Igor Garkusha  [комментарии]
 
Задача: Организовать автоматизированное подключение Windows-клиента
к Linux-серверу терминалов через программу PuTTY (по ssh-протоколу) в связке с
XMing. Windows-клиент имеет в домене
гостевой профиль (все настройки после выхода из системы сбрасываются). Имена
пользователей из домена Windows и на сервере терминалов совпадают(!).

Основная проблема: все свои настройки PuTTY хранит в реестре
Windows, что делает невозможным их повторное использование после гостевого входа.

Пути решения.

1. Перед выходом из сеанса работы с PuTTY сохранять его ветку рееестра с
настройками. Недостаток: решение не является универсальным и гибким. Например,
старт X сервера необходимо выполнять отдельно указывая каждый раз
пользовательские настройки, что есть длинный путь для гостя.

2. Создать специальный скрипт(ы), автоматизирующий подключение PuTTY.

Рассмотрим второй вариант. 

Пусть IP-адрес Linux-сервера 10.0.0.1, 
локаль пользователя Linux в кодировке UTF-8, 
X сервер XMing установлен в каталог "C:\Program Files\Xming".

Создадим, например, следующую структура каталогов и файлов:

	каталог XServer
		файл StartTerminal.cmd
		каталог config
			файл do_start_terminal.cmd
			файл start_XServer.js
			файл config.xlaunch
			файл putty.prog (переименованный putty.exe)

Скрипт StartTerminal.cmd:

   @echo off
   SET XMING_SRV_PATH="C:\Program Files\Xming"

   SET REMOTE_SERVER=10.0.0.1

   SET REMOTE_CODEPAGE_LOCALE=UTF-8

   cmd /C %CD%\config\do_start_terminal.cmd %XMING_SRV_PATH% %REMOTE_SERVER% %REMOTE_CODEPAGE_LOCALE%

Скрипт config\do_start_terminal.cmd:

   @echo off

   cmd /C %CD%\config\start_XServer.js %1

   reg add HKCU\Software\SimonTatham\PuTTY\Sessions\User /v HostName /t REG_SZ /d %2 /f

   reg add HKCU\Software\SimonTatham\PuTTY\Sessions\User /v LineCodePage /t REG_SZ /d %3 /f

   reg add HKCU\Software\SimonTatham\PuTTY\Sessions\User /v X11Forward /t REG_DWORD /d 1 /f

   reg add HKCU\Software\SimonTatham\PuTTY\Sessions\User /v UserName /t REG_SZ /d %USERNAME% /f

   reg add HKCU\Software\SimonTatham\PuTTY\Sessions\User /v X11Display /t REG_SZ /d %COMPUTERNAME% /f

   start %CD%\config\putty.prog

Скрипт config\start_XServer.js:

   var XLaunchPath = WScript.Arguments(0);

   var WshShell = WScript.CreateObject("WScript.Shell");

   var cfgPath= WshShell.CurrentDirectory+"\\config\\config.xlaunch";

   var execPath = XLaunchPath + "\\XLaunch.exe -run " + cfgPath;

   WshShell.Exec(execPath);


Файл настроек XMing config\config.xlaunch (можно заранее подготовить при помощи программы XLaunch):

   <?xml version="1.0"?>

   <XLaunch xmlns="http://www.straightrunning.com/XmingNotes"  
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://www.straightrunning.com/XmingNotes XLaunch.xsd" 
     WindowMode="MultiWindow" ClientMode="NoClient" Display="0" Clipboard="true" 
     ExtraParams="-xkblayout us,ru -xkbvariant basic,winkeys -xkboptions grp:caps_toggle -dpi 96"/>


После запуска скрипта StartTerminal.cmd в окне программы PuTTY необходимо
выбрать из списка настройки User, нажать на кнопку Load, а затем на Open. Далее
согласиться с диалогом по поводу ssh и в окне терминала ввести пароль пользователя.

Представленная скриптовая схема является гибкой и позволяет проводить всю
необходимую автоматизацию настроек PuTTY, а также запуск X сервера XMing с
нужными параметрами.
 
----* Как удержать SSH-соединение от обрыва при использовании Socks   [комментарии]
 
При выходе в сеть через Socks-прокси ssh-соединение часто разрывается после
небольшого интервала неактивности (иногда достаточно несколько секунд).
Чтобы этого не произошло необходимо использовать опцию ServerAliveInterval=N,
которая заставляет ssh через N секунд отправлять alive-пакеты, не дающие
автоматически оборвать соединение из-за истечения таймаута.

Пример:

   tsocks ssh -o ServerAliveInterval=3 myhost.test.ru
 
----* Создание HTTP-туннеля для удаленного доступа к Linux-хосту в обход Microsoft ISA (доп. ссылка 1)   [комментарии]
 
Для организации управления внешней рабочей станцией из корпоративной сети,
защищенной Microsoft ISA, можно поднять HTTP-туннель, при помощи которого можно
установить TCP-соединение, несмотря на использование HTTP-прокси и жестких
политик ограничения доступа на межсетевом экране.

Использовать классический пакет GNU HTTPtunnel
(http://www.gnu.org/software/httptunnel/) в такой ситуации мешает отсутствие
поддержки в данной программе  NTLM-аутентифиукации, как правило используемой
при организации выхода пользователей в сеть через Microsoft ISA. Выходом в
данной ситуации является использование программы BoutDuTunnel
(http://boutdutunnel.net/), совместимой с большинством HTTP-прокси,
поддерживающей NTLM-аутентифиукацию, способной работать даже при блокировании
HTTPS и метода "Connect", содержащей в себе встроенный HTTP-сервер и
поддерживающей работу поверх Socks.

BoutDuTunnel поддерживает работу из Linux и Windows, при запуске из Linux
достаточно установить пакет mono и загрузить готовый исполняемый файл bdtunnel
(http://sourceforge.net/projects/bdtunnel/files/).

После установки правим на стороне удаленного сервера файл BdtServerCfg.cfg в
директории BdtServer, приведя его примерно в такой вид:

   <service
      name = "BdtServer"
      protocol = "Bdt.Shared.Protocol.TcpRemoting"
      port = "80"
    />

   <users>
      <имя_пользователя
         enabled = "true"
         password = "пароль"
         admin = "false"
         stimeout = "12"
         ctimeout = "1"
      />
   </users>

, где name - имя туннеля (должно быть одинаковым на обоих концах туннеля),
protocol - тип туннельного протокола, port - номер серверного порта для
формирования туннеля. Секция "users" определяет параметры авторизации для
создания туннеля и таймауты для сброса неактивных сессий и соединений.

После настройки запускаем на стороне удаленного сервера (привилегии
суперпользователя нужны для организации приема соединений на 80 порту):

   sudo mono BdtServer.exe

На стороне клиента, находящегося в локальной сети за прокси-сервером, правим
файл BdtClientCfg.xml в директории BdtGuiClient, приведя его к виду:

   <service
      name="BdtServer"
      protocol="Bdt.Shared.Protocol.TcpRemoting"
      address="адрес удаленного сервера"
      port="80"
      username="имя пользователя"
      password="пароль"
      culture=""
   />

   <port22
      enabled="true"
      shared="false"
      address="адрес удаленного сервера"
      port="22" 
   />

Секция port22 определяет проброс 22 порта на удаленный сервер, что позволит
использовать протокол SSH или работающие поверх него сервисы, например, rsync,
git, NX Client.

Запускаем BdtGuiClient.exe, после чего при соединении к localhost по 22 порту
будет автоматически произведен переброс на 22 порт удаленного сервера, при этом
с точки зрения прокси будет установленно классическое HTTP-соединение, так как
на удаленном конце BoutDuTunnel выступает в роли HTTP-сервера, а не использует
HTTPS-метод "Connect".

Для противников Mono вместо BoutDuTunnel можно рекомендовать имеющийся в
стандартных репозиториях Debian/Ubuntu пакет proxytunnel
(http://proxytunnel.sourceforge.net/), который также поддерживает
NTLM-аутентификацию, но может работать только на Unix-совместимых системах и
требует включения метода connect на прокси.

Для проброса 22 порта поверх HTTP-прокси при использовании proxytunnel
достаточно прописать в файл конфигурации OpenSSH ~/.ssh/config:

   ProtocolKeepAlives 30
   ProxyCommand /usr/bin/proxytunnel --ntlm -p хост_прокси:порт_прокси -u логин -s пароль -d удаленный_сервер:443
 
----* Escape-последовательность для ssh (доп. ссылка 1)   Автор: Аноним  [комментарии]
 
Многим известна escape-последовательность ^], используемая клиентом telnet для
перехода в командный режим. Однако, не все знают о существовании
escape-последовательности в ssh-клиенте.

Если в вашем дистрибутиве она не включена по умолчанию, то это можно сделать
добавив в файл конфигурации ssh_config следующую опцию:

   EscapeChar ~

Теперь вы можете:

   ~?  получить список всех команд клиента
   ~.  оборвать подвисшую сессию
 
----* Автодополнение ssh-хостов в командной строке (доп. ссылка 1)   Автор: bthemad  [комментарии]
 
Простейшим способом упрощения набора параметров для частоиспользуемых хостов
является задание псевдонимов в ~/.ssh/config:

   Host        myhost      # Имя хоста
   HostName    server.com  # Это удаленнй хост
   User        username    # Пользователь на удаленном хосте
   Port        22222       # Номер порта

При этом вместо "ssh -p 22222 -l username server.com" теперь достаточно написать "ssh myhost".

В случае когда этого недостаточно и хочется получить в bash поддержку
автодополнения типовых имен хостов можно добавить в ~/.bashrc или ~/.profile
следующие конструкции.

При поиске имен среди параметров Host и HostName в ~/.ssh/config:

   complete -W "$(echo `cat ~/.ssh/config | grep -iE '^(Host|HostName) ' | awk '{print $2}'`)" ssh


Обычно в дистрибутивах Linux уже присутствует настройка (/etc/bash_completion)
для автодополнения по содержимому файла known_hosts, но в последних версиях
OpenSSH имена хостов в данном файле перестали задаваться в открытом виде,
поэтому автодополнение не работает. Тем не менее хэширование имен можно
отключить указав в ssh_config "HashKnownHosts no".

Для поиска по known_hosts может быть использована конструкция:

   complete -W "$(echo `cat ~/.ssh/known_hosts | cut -f 1 -d ' ' | sed -e s/,.*//g | uniq | grep -v "\["`;)" ssh


Более развернутый пример запроса для организации автодополнения по содержимому
первого столбца произвольного файла my_hosts.txt:

   _compssh ()
   {
   cur=${COMP_WORDS[COMP_CWORD]};
   COMPREPLY=($(compgen -W '$(cut -d " " -f1 ~/my_hosts.txt) --all --schema' -- $cur))
   }
   complete -F _compssh ssh
 
----* Защищаем SSH при помощи технологии "Port Knocking" (доп. ссылка 1) (доп. ссылка 2)   Автор: Дмитрий  [комментарии]
 
Реализация идеи динамического открытия доступа к 22 порту, при предварительном
обращении telnet-ом на определенный сетевой порт (в примере 333 - открыть
доступ и 334 - закрыть). Идея реализована средствами iptables, без привлечения
дополнительных утилит и анализаторов логов.

   # Создаю цепочку с именем SSH
   iptables -N SSH
   # Правило по умолчанию в INPUT - DROP
   iptables -P INPUT DROP 
   # Всё что пришло на 22 порт - в цепочку SSH
   iptables -A INPUT -p tcp --dport 22 -j SSH 
   # Всё что пришло на 333 порт - в цепочку SSH
   iptables -A INPUT -p tcp --dport 333 -j SSH 
   # Всё что пришло на 334 порт - в цепочку SSH
   iptables -A INPUT -p tcp --dport 334 -j SSH 

Разделения на цепочки сделано для своего удобства, от этого можно и отказаться. 

Теперь заполняем цепочку SSH.

   # Проверяем на наличие имени "SSH" у IP адреса устанавливающего соединение на 22 порт. 
   # И если оно присутствует - то ACCEPT
   iptables -A SSH -p tcp -m state --state NEW -m tcp --dport 22 -m recent --rcheck --name SSH --rsource -j ACCEPT

   # Устанавливает имя SSH любому IP адресу с которого пришло новое TCP соединение на указанный порт. (порт 333)
   iptables -A SSH -p tcp -m state --state NEW -m tcp --dport 333 -m recent --set --name SSH --rsource -j DROP

   # Удаляет имя "SSH" с IP адреса установившего соединение на этот порт. (порт 334)
   iptables -A SSH -p tcp -m state --state NEW -m tcp --dport 334 -m recent --remove --name SSH --rsource -j DROP

Насладимся итоговым результатом: 

Делаем: 
   telnet ip_address_or_domain_name 333
После чего спокойно подключаемся по SSH.

Когда прекращаем работу закрываем за собой 22 порт:
   telnet ip_address_or_domain_name 334
 
----* Сопоставление логинов и хостов для упрощения входа по SSH (доп. ссылка 1)   [комментарии]
 
При использовании разных имен пользователей на разных хостах часто приходится
долго перебирать их и вспоминать,
какой из аккаунтов заведен для данной машины. OpenSSH позволяет определить,
какое из имен использовать
для данного хоста по умолчанию. 

Пример настроек .ssh/config:

   Host *.test1.ru
     ServerAliveInterval 60
     User user1

   Host *.test2.ru
     Compression yes
     ForwardX11 yes
     IdentityFile ~/.ssh/id_dsa_ext
     User user2

Теперь при входе "ssh test.test1.ru" будет использовано имя user1, а при "ssh
host.test2.ru" - имя user2.
 
----* Поддержание SSH-туннеля в активном состоянии при помощи AutoSSH (доп. ссылка 1) (доп. ссылка 2)   Автор: Roman Sozinov  [комментарии]
 
Иногда необходимо иметь возможность удалённо управлять какими-то системами,
которые находятся за firewall'ами,
которые Вы не контролируете. В таких случаях помогают ssh-тунели с использованием перенаправления 
(forwarding) портов. Например, допустим имеется удалённая машина trick, которая
находится за маршрутизатором
в удалённой локальной сети, и вторая машина rose имеющая внешний ip-адрес. Для того, чтобы иметь 
возможность с rose заходить на trick (либо использовать какой-то сервис на
trick), необходимо поднять
туннель с использованием перенаправления удаленных портов (remote port forwarding):

   ssh -f -N username@rose -R 3722:127.0.0.1:22

Получаем такую картину: на rose в списке открытых портов появляется порт 3722,
который на самом деле
перенаправляет все пакеты на 22-й порт trick-системы. После этого можно
логиниться через ssh на trick из rose:

   ssh username@127.0.0.0 -p 3722

А что делать, чтобы тунели были постоянно доступны? Ведь ssh-соединения бывают рвутся 
и тогда опять необходимо с trick-системы инициировать тунель. А если trick
находится в 100 км от Вас?
А если их таких у Вас 20? :) Вот тут-то и помогает замечательная вещь -
autossh, утилитка занимающаяся тем,
что поддерживает поднятые ssh-туннели в рабочем состоянии. Перед её запуском необходимо установить 
переменную AUTOSSH_PORT, указывающую номер порта, который будет использоваться
для heartbeat-пакетов
на предмет того - жив ли тунель.

Также, если туннели необходимо поднимать во время старта системы, советуют установить переменную 
AUTOSSH_GATETIME=0. Переменная AUTOSSH_DEBUG позволит получить из логов
дополнительную информацию о ходе процесса.

   export AUTOSSH_DEBUG=1
   export AUTOSSH_GATETIME=0
   export AUTOSSH_PORT=20037
   autossh -f -N username@rose -R 3722:127.0.0.1:22

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

В приведенном выше примере кроме портов rose:3722 и trick:22 поднимается ещё 3 дополнительных 
(так как установлена переменная AUTOSSH_PORT) - trick:20037, rose:20037, trick:20038, связанных 
между собой в цепочку для прохождения heartbeat-пакета. Таким образом, что отправляя запрос 
на trick:20037, пакет приходит на rose:20037, который в свою очередь
перенаправляет его дальше на trick:20038.
Получается своеобразный "бумеранг", позволяющий следить за туннелем.
 
----* Помещение OpenSSH пользователей в изолированное sftp окружение (доп. ссылка 1)   [комментарии]
 
Начиная с релиза 4.9 в OpenSSH появилась возможность помещать отдельных
пользователей в изолированное окружение.
Помещение в chroot управляется через директиву ChrootDirectory, задаваемую в
конфигурационном файле sshd_config.
При задействовании sftp-server интегрированного в sshd, при этом не требуется
формирование специального chroot окружения.

Пример помещения в chroot:

   AllowUsers user1 user2 user3@192.168.1.1 user3@192.168.2.*
   Match user user2, user3
         ChrootDirectory /home/%u
         X11Forwarding no
         AllowTcpForwarding no
         ForceCommand internal-sftp

   Subsystem       sftp    internal-sftp

Пользователь user1 имеет возможность входа в shell, в то время как user2 и
user3 могут работать только по sftp,
без возможность выхода за пределы своей домашней директории.
При этом user3 может входить только с машины 192.168.1.1 и подсети 192.168.2.0/24.

Опция "ForceCommand internal-sftp" разрешает пользователю использовать только
sftp, встроенный в sshd.

Директория, в которую происходит chroot пользователя (не имеет значения, ssh или sftp), 
должна принадлежать пользователю root и права на запись должны принадлежать
только владельцу (750, например).

При необходимости пускать пользователей в shell, необходимо сформировать
минимальное chroot-окружение,
скопировав туда необходимые для работы программы и библиотеки.

Например, создадим для пользователей, входящих в группу chrootusers, окружение /home/chroot

В /etc/ssh/sshd_config добавим:

   Match Group chrootusers
       ChrootDirectory /home/chroot
       X11Forwarding no
       AllowTcpForwarding no

Для формирования chroot можно использовать скрипт make_chroot_jail.sh,
поддерживающий Debian, Suse, Fedora и Redhat Linux:
   http://www.fuschlberger.net/programs/ssh-scp-sftp-chroot-jail/

Также можно порекомендовать скрипт sync_chroot.pl (ftp://ftp.opennet.ru/pub/security/chroot/ ), 
который автоматически находит и копирует в chroot недостающие библиотеки для
находящихся внутри chroot программ.

Рассмотрим создание chroot в Debian или Ubuntu Linux.

Установим необходимые для работы скрипта утилиты:

   apt-get install sudo debianutils coreutils

Копируем скрипт make_chroot_jail.sh:

   wget http://www.fuschlberger.net/programs/ssh-scp-sftp-chroot-jail/make_chroot_jail.sh
   chmod 700 ./make_chroot_jail.sh

Определяем список программ для chroot-окружения, в make_chroot_jail.sh находим
строки и меняем на свое усмотрение:

   ...
   elif [ "$DISTRO" = DEBIAN ]; then
     APPS="/bin/bash /bin/cp /usr/bin/dircolors /bin/ls /bin/mkdir \
     /bin/mv /bin/rm /bin/rmdir /bin/sh /bin/su /usr/bin/groups \
     /usr/bin/id /usr/bin/rsync /usr/bin/ssh /usr/bin/scp \
     /sbin/unix_chkpwd /usr/bin/vi"
   else
   ...

Формат вызова скрипта:
   make_chroot_jail.sh логин путь_к_shell путь_к_chroot

Для создания окружения с shell по умолчанию bash для пользователя user1 выполним:

   ./make_chroot_jail.sh user1 /bin/bash /home/jail

При этом скрипт автоматически скопирует все недостающие в chroot файлы и
создаст директорию /home/jail/user1

После обновления базовой системы, обновить chroot можно командой:

   ./make_chroot_jail.sh update /bin/bash /home/jail
 
----* Организация подключения по SSH через HTTP прокси   [комментарии]
 
Устанавливаем ПО corkscrew (http://www.agroman.net/corkscrew/), позволяющее
создавать туннели поверх HTTP прокси.

Например, для Debian/Ubuntu:
   apt-get install corkscrew

Для FreeBSD:
   cd /usr/ports/net/corkscrew && make && make install


Создаем в домашней директории файл настроек .proxy-auth в который прописываем логин и пароль 
для подключения к прокси, в формате "имя:пароль", например:

   moi_login:moi_parol

Настраиваем проброс туннеля в SSH. В ~/.ssh/config добавляем:

   Host *
   ProxyCommand corkscrew хост_прокси_сервера порт_прокси_сервера %h %p ~/.proxy-auth

Вместо %h и %p ssh подставит хост и порт удаленной машины

Подключаемся к внешнему хосту стандартно:

   ssh testhost.ru
 
----* Повторное использование открытых OpenSSH соединений и кеширование ключей (доп. ссылка 1)   [комментарии]
 
В OpenSSH предусмотрена возможность использования существующих соединений, при
повторном коннекте к хосту.

При этом аутентификация будет осуществлена только при первом соединении, для
всех остальных соединениях вводить пароль не потребуется.

Создаем или модифицируем файл ~/.ssh/config:

   Host *
   ControlMaster auto 
   ControlPath ~/tmp/%r@%h:%p

В ControlPath определяем параметры управляющего сокета, например, в нашем случае 
сокет будет создан в поддиректории tmp домашнего каталога текущего пользователя.

При использовании туннелей, режим ControlMaster следует запретить, используя
опцию командной строки:
   "-o ControlMaster=no"

Например, для ssh транспорта subversion можно прописать в ~/.subversion/config:

   [tunnels]
   ssh = ssh -o ControlMaster=no


Для кеширования приватных ключей, созданных командой ssh-keygen и используемых 
для публичной идентификации в OpenSSH можно использовать ssh-agent.

В простейшем случае достаточно предварить запуск терминальной сессий вызовом ssh-agent:

   ssh-agent gnome-terminal

Далее выполняем 
   
   ssh-add

и вводим пароль для доступа к ключу ~/.ssh/id_rsa (путь к файлу с ключом может быть 
задан в качестве аргумента), после чего в пределах процесса gnome-terminal
вводить пароль для данного ключа не потребуется.

Обычно ssh-agent выпоняют в привязке ко всей X сессии пользователя, напирмер, 
в Ubuntu запуск x-session-manager под управлением ssh-agent уже прописан в /etc/X11/Xsession.options

Вручную, прописать запуск ssh-agent можно в .xsession, например, для старта  gnome-session:

   ssh-agent gnome-session
 
----* Туннели с использованием SSH. Режим эмуляции Socks proxy в SSH (доп. ссылка 1) (доп. ссылка 2)   Автор: Vladimir Brednikov  [комментарии]
 
1. Режим эмуляции Socks proxy в SSH

Допустим, у нас есть рабочая станция в локальной сети за firewall'ом;
также имеется ssh-доступ на сервер в Интернете. Кроме ssh, никакой связи с
внешним миром не имеется,
а очень хочется, например, подключиться к какому-нибудь jabber-серверу.

На рабочей станции запускаем простую команду:

   ssh -D 5555 user@remotehost -f -N

, где -D 5555 - эмуляция SOCKS сервера через порт 5555 
-f  - работа в фоне, после аутентификации
-N - не запускать shell на удаленном хосте.

Теперь, указав в настройках XMPP-клиента (например, Pidgin'а) в качестве SOCKS5
прокси localhost:5555,
получим желаемый результат: Pidgin соединяется с сервером через внешний сервер.


2. Туннель ssh

Дано: сервер локальной сети ourproxy.provider.ru, доступный извне.

Требуется: получить из дома доступ к ресурсам внутри локальной сети, например,
к интранет-серверу 10.10.5.1:80

Решение: выполнить на домашней машине команду, пробрасывающую туннель к
искомому IP-адресу через ourproxy.provider.ru:

    ssh -f -N user@ourproxy.provider.ru -L 8080:10.10.5.1:80

Опция -f говорит ssh, что после соединения нужно уйти в background.
Опция -N указывает, что никаких команд выполнять не нужно
Ключ -L означает, что соединения к localhost на порт 8080 нужно перенаправлять
на 80 порт IP-адреса 10.10.5.1

Таким образом, набирая в браузере адрес http://localhost:8080, попадаем на нужный сервер.


3. Обратный туннель ssh


Дано: компьютер на работе, находящийся за firewall'ом и nat'ом; компьютер дома
с доступом в интернет;
сервер ourproxy.provider.ru с работающим sshd, доступный обоим компьютерам. 
Но в данном случае прямой доступ с ourproxy.provider.ru к рабочей машине отсутствует.

Требуется: получить из дома доступ к сервису sshd на рабочем компьютере.

Решение: на рабочей машине выполнить команду:

    ssh -f -N user@ourproxy.provider.ru -R 12345:localhost:22

Опции -f и -N описаны несколькими строчками выше.
Ключ -R означает, что подключения к порту 12345 на ourproxy.provider.ru будут
перенаправляться на 22 порт рабочего компьютера.

После выполнения этой команды с рабочей машины можно будет попасть на эту
машину с ourproxy.provider.ru,
выполнив команду:

    ssh -p 12345 user@locahost

По этому же принципу можно получить доступ к прочим ресурсам локальной сети. Вот еще один пример.

На рабочей машине:

    ssh -f -N user@ourproxy.provider.ru -R 8080:10.10.5.1:80

На домашней машине:

    ssh -f -N user@ourproxy.provider.ru -L localhost:8080:localhost:8080

Теперь, набрав в адресной строке браузера на домашнем компьютере http://localhost:8080, 
получаем доступ к интранет-серверу за семью замками двумя firewall-ами.

Конечно же, это приводит к серьёзной бреши в корпоративной безопасности, 
поэтому крайне не рекомендуется злоупотреблять этим советом.
 
----* Безопасный способ копировать бэкапы через ssh (доп. ссылка 1)   Автор: mahoro  [комментарии]
 
Опция "command" файла authorized_keys позволяет указать команду, которая будет
выполняться при каждом подключении пользователя по ssh.

Это удобно, когда стоит задача копировать файлы на бэкап-сервер.
Например, если необходимо предоставить доступ только к файлу backup.tgz, 
то допишите строку "command='cat backup.tgz'" в самое начало строки с нужным
ключом файла authorized_keys.
Указанная команда будет выполняться автоматически при каждом подключении, 
вам остается только перенаправить вывод в файл. Если дампов несколько, 
то можно написать небольшой скрипт, вида:

   #!/bin/sh
   read file
   case "$file" in
      "foo") cat foo.tgz ;;
      "bar") cat bar.tgz ;;
   esac

Кроме command, в таких случаях не лишним было бы добавить также опции
no-port-forwarding, no-pty и все прочие no-*

Кроме как для бэкапов, такое же решение может подойти и для мониторинга. 
Когда nagios соединяется к удаленному серверу, чтобы собрать какую-либо
статистику, полный ssh-доступ ему не нужен.

В OpenSSH 4.9 появилась возможность помещать отдельных пользователей в изолированное окружение. 
Помещение в chroot управляется через директиву ChrootDirectory, задаваемую в
конфигурационном файле sshd_config.
Также в sshd был встроен sftp-server и теперь не требует запуска отдельного процесса, 
что идеально подходит для использования совместно с директивами ChrootDirectory
и ForceCommand internal-sftp.

Например, для ограничения работы пользователя backup только по sftp в пределах директории /chroot:

   Match user backup
       ForceCommand internal-sftp
       ChrootDirectory /chroot
  ...
  #Subsystem      sftp    /usr/libexec/sftp-server
  Subsystem       sftp    internal-sftp

Пример копирования:

  echo "PUT backup.tgz" | sftp backup@backupserver.ru:/backup/

В настоящий момент в sshd не произведена интеграция scp, т.е. при использовании scp, 
по-прежнему требуется копирование библиотек в chroot окружение.
 
----* Автоблокирование атак по подбору паролей (brute force) в SSH под FreeBSD (доп. ссылка 1)   Автор: Roman Y. Bogdanov  [комментарии]
 
Устанавливаем sshguard из портов:

   cd /usr/ports/security/sshguard
   make install clean WITH_PF=yes

Настраиваем перенаправление логов в sshguard

   echo "auth.info;authpriv.info |exec /usr/local/sbin/sshguard" >> /etc/syslog.conf

Правила блокировки по таблице, /etc/pf.conf

   internet="vlan50"
   table persist
   block in quick on $internet from label "ssh bruteforce"

Перечитываем измененные файлы конфигурации PF и syslogd:

   pfctl -f /etc/pf.conf
   /etc/rc.d/syslogd restart

Тестируем попробовав подобрать пароли:
   shguard[1048576]: Started successfully [(a,p,s)=(4, 420, 1200)], now ready to scan.

   sshd[1048577]: Invalid user administrador from 21.138.24.51
   sshd[1048579]: Invalid user publica from 21.138.24.51
   sshd[1048580]: Invalid user rbecerril from 21.138.24.51
   sshd[1048581]: Invalid user rvences from 21.138.24.51

   sshguard[1048582]: Blocking 21.138.24.51: 4 failures over 15 seconds.
   shguard[1048583]: Releasing 21.138.24.51 after 490 seconds.
 
----* Как скрыть отображаемую версию OpenSSH   Автор: Вотинцев Сергей А,  [комментарии]
 
Для OpenSSH из FreeBSD, в /usr/src/crypto/openssh/version.h меняем, например, на это:
   #define SSH_VERSION_BASE        "OpenSSH"
   #define SSH_VERSION_ADDENDUM    "Beastie"

пересобираем:
   cd /usr/src/secure/usr.sbin/sshd 
   make obj && make depend && make all install

и имеем SSH-2.0-OpenSSH Beastie вместо SSH-2.0-OpenSSH_3.6.1p1 FreeBSD-200xxxxx.
 
Некоторые пакеты с OpenSSH (например в AltLinux) включают в себя патч от http://openwall.com, 
добавляющий директиву  SshVersion:
    SshVersion  OpenSSH-1.2.3
 
----* Как создать шифрованный туннель используя SSH (доп. ссылка 1)   [комментарии]
 
ssh dmzserver -R 9999:mirrorserver:80
ssh -R 9999:localhost:80 dmzserver
ssh -2 -N -f -L 2110:mail.example.com:110 user@ssh-server.example.com
 
----* Как включить доступ на Cisco через ssh (доп. ссылка 1)   [комментарии]
 
hostname имя_хоста
ip domain-name доменное_имя
crypto key generate rsa
ip ssh time-out 120
ip ssh authentication-retries 3
line vty 0 4 
  transport input telnet ssh 
!
show crypto key mypubkey rsa
 
----* Как настроить доступ по SSH на базе секретных ключей без ввода пароля.   [комментарии]
 
В /etc/ssh/sshd_config проверяем активна ли опция "PubkeyAuthentication yes".
Запускаем на локальной машине программу ssh-keygen (ssh-keygen -t rsa),
 на все задаваемые вопросы принимаем значения по умолчанию (поле passphrase оставляем пустым).
Далее, запускаем программу ssh-copy-id -i ~/.ssh/id_rsa.pub user@remotehost, где
   user - пользователь удаленной машины 
   remotehost - адрес удаленной машины,
( или вручную, на удаленной машине в директории ~/.ssh, создаем файл authorized_keys, 
куда копируем содержимое файла identity.pub (id_rsa.pub) с локальной машины). 
Для увеличения безопасности в файл ~/.ssh/authorized_keys на удаленной машине 
добавляем перед ключом (разделив пробелом) строку:
    from="localhost", где localhost - адрес локальной машины (from="localhost" 1024 23 1343.....).
 
----* Какие ограничения лучше включить для SSHD ?   [обсудить]
 
В /etc/ssh/sshd_config:
 AllowUsers user1 user2 user3@host.ru
 ChallengeResponseAuthentication no
 PermitEmptyPasswords no
 PermitRootLogin no
 Protocol 2
 UseLogin no
 X11Forwarding no
 UsePrivilegeSeparation yes
# убрать все Subsystem
Ограничить вход только с определенных IP через /etc/hosts.allow
 
----* Как скопировать группу файлов на удаленную машину.   [комментарии]
 
С локальной на удаленную:
tar czvf - список_файлов_и_директорий | ssh remote.test.ru tar xzf - -C /home/user/куда_копировать 
Скопировать группу файлов с удаленной машины на локальную.
ssh remote.test.ru tar czf - -C стартовая_директория какие_файлы_копировать
|tar xzf - -C директория_куда_копировать.
 

   Виртуализация - Xen, OpenVZ, KVM, Qemu

----* Обновление сертификатов oVirt   Автор: casm  [комментарии]
 
oVirt - свободная, кроссплатформенная система управления виртуализацией.
Была разработана компанией Red Hat как проект сообщества, на котором основан
продукт Red Hat Virtualization.

oVirt состоит из двух основных компонентов - oVirt engine и oVirt node.

oVirt engine управляет всеми хостами виртуализации, общими дисковыми ресурсами
и виртуальными сетями. Может быть размещён как на отдельном сервере
(standalone), так и на виртуальной машине внутри гипервизоров, которыми
управляет (self-hosted engine).

oVirt node - физический сервер с RHEL, Centos, Scientific Linux с KVM
гипервизором и службой VDSM (Virtual Desktop and Server Manager), которая
управляет всеми ресурсами, доступными серверу (вычисления, ОЗУ, хранилище,
сеть), а также управляет запуском виртуальных машин. Несколько узлов могут быть
объединены в кластер.

В примерах ниже будут один oVirt engine и три oVirt node:

  • oVirt engine - virt-he.example.test
  • oVirt node - virt-host1.example.test, virt-host2.example.test, virt-host3.example.test Обмен данными между oVirt engine и oVirt node осуществляется с использованием SSL-сертификатов. Автоматическое обновление сертификатов не производится, поэтому очень важно обновлять сертификаты вручную до истечения сроков их действия. Стандартными средствами обновить сертификаты можно, если до окончания срока действия осталось менее 60 дней (для версии 4.5). В oVirt необходимо обновлять вручную два типа сертификатов:
  • сертификаты oVirt Engine - службы, которая предоставляет графический интерфейс и REST API для управления ресурсами виртуальных машин
  • сертификаты для обмена данным между гипервизорами oVirt node и центром управления виртуальными машинами oVirt Engine Определить дату окончания действия сертификатов oVirt Engine можно в свойствах сертификата сайта. Определить дату окончания действия сертификатов oVirt node можно с помощью openssl:
  • Подключаемся через SSH на физический сервер oVirt node
  • Определяем дату: [root@virt-host1 ~]# openssl x509 -noout -enddate -in /etc/pki/vdsm/certs/vdsmcert.pem В версиях oVirt до 4.5, у всех сертификатов время жизни составляет 398 дней. Начиная с версии 4.5, у самоподписанных сертификатов для обмена данным между гипервизорами oVirt node и центром управления виртуальными машинами oVirt engine установлено время действия 5 лет. У сертификатов, которые видят браузеры, срок действия установлен в 398 дней, их необходимо обновлять раз в год. Процедура обновления действующих сертификатов описана в официальной документации. Если вы допустите истечение срока действия сертификатов, то гипервизоры и центр управления Engine перестанут взаимодействовать. В Web-консоль невозможно будет войти, виртуальные машины продолжать работать, но с ними ничего нельзя будет сделать: нельзя изменить параметры виртуального железа, нельзя мигрировать на другой узел, после выключения ВМ её будет невозможно включить снова. Восстановление займёт много времени. Процедура восстановления просроченных сертификатов описана в руководстве. Для доступа к нему необходима действующая платная подписка Red Hat Virtualization (RHV) 4.x. Решение для восстановления без подписки я обнаружил на GitHub. Автор подготовил решения для Ansible в соответствии с рекомендациями от Red Hat. Если вы знакомы с Ansible и у вас много гипервизоров с просроченными сертификатами, то можно использовать решение от natman. Решение ниже подходит для небольшого числа гипервизоров, но при условии, что центр управления Engine у вас запущен, и вы можете получить к нему доступ через ssh. Предполагается, что в качестве центра управления используется HostedEngine - центр управления гипервизорами запускается внутри самого гипервизора. Если центр управления Engine выключен и не запускается, а в журнале journalctl на гипервизоре появляются записи libvirtd[2101]: The server certificate /etc/pki/vdsm/certs/vdsmcert.pem has expired ... systemd[1]: Failed to start Virtualization daemon то единственным вариантом восстановления будет изменение времени на гипервизоре на более ранее (в пределах срока действия сертификатов) и обновление сертификатов стандартным образом. Обновление сертификатов до истечения сроков действия Обновление сертификатов oVirt node Переводим узел (гипервизор) в режим обслуживания (Managеment -> Maintenance) - все машины на узле будут мигрированы, привязанные (pinned) машины будут выключены. Выбираем Installation -> Enroll Certificate Выводим узел из режима обслуживания Повторяем операции для всех оставшихся узлов в кластере Обновление сертификатов oVirt Engine Подключаемся к физическому серверу гипервизору oVirt node через SSH С узла Ovirt host переводим центр управления ВМ в режим обслуживания (для Self-hosted типа развёртывания) [root@virt-host1 ~]# hosted-engine --set-maintenance --mode=global Подключаемся к виртуальной машине с центром управления oVirt engine через SSH, запускаем настройку engine (web-консоль будет остановлена) [root@virt-he ~]# engine-setup --offline Отвечаем на вопросы Если до истечения срока действия сертификата осталось менее 60 дней, то скрипт предложит обновить сертификаты: Renew certificates? (Yes, No) [No]: Yes Дожидаемся окончания работы скрипта. С узла Ovirt host выводим центр управления ВМ из режима обслуживания: [root@virt-host1 ~]# hosted-engine --set-maintenance --mode=none Подключаемся к web-консоли и проверяем дату окончания действия сертификата. Обновление сертификатов после истечения сроков действия Если вы допустите истечение срока действия сертификатов, то в web-консоль невозможно будет войти. Гипервизоры и центр управления Engine перестанут взаимодействовать. Чтобы восстановить сертификаты выполняем следующие шаги. Подключаемся через SSH на узел гипервизора oVirt node с истёкшим сертификатом (в примере имя узла virt-host1). Создаем запрос сертификата на основании ключа службы VDSM /etc/pki/vdsm/keys/vdsmkey.pem [root@virt-host1 ~]# openssl req -new \ -key /etc/pki/vdsm/keys/vdsmkey.pem \ -out /tmp/test_virt-host1_vdsm.csr \ -batch \ -subj "/" Подписываем запрос с помощью корневого сертификата oVirt engine, для этого подключаемся через SSH на ВМ с oVirt engine, копируем запрос с oVirt node (virt-host1) на oVirt engine в /tmp и выполняем команды [root@virt-he ~]# cd /etc/pki/ovirt-engine/ [root@virt-he ~]# openssl ca -batch \ -policy policy_match \ -config openssl.conf \ -cert ca.pem \ -keyfile private/ca.pem \ -days +"365" \ -in /tmp/test_virt-host1_vdsm.csr \ -out /tmp/test_virt-host1_vdsm.cer \ -startdate `(date --utc --date "now -1 days" +"%y%m%d%H%M%SZ")` \ -subj "/O=example.test/CN=virt-host1.example.test\ -utf8 Имя субъекта в сертификате должно быть в формате "/O=example.test/CN=virt-host1.example.test", укажите ваши значения. Копируем новый сертификат с oVirt engine на oVirt node (virt-host1) в /tmp. Копируем новый сертификат в каталоги служб предварительно создав копию существующих сертификатов [root@virt-host1 ~]# cp /etc/pki/vdsm/certs/vdsmcert.pem /etc/pki/vdsm/certs/vdsmcert.pem.bak [root@virt-host1 ~]# cp /tmp/test_virt-host1_vdsm.cer /etc/pki/vdsm/certs/vdsmcert.pem [root@virt-host1 ~]# cp /etc/pki/vdsm/libvirt-spice/server-cert.pem /etc/pki/vdsm/libvirt-spice/server-cert.pem.bak [root@virt-host1 ~]# cp /etc/pki/vdsm/certs/vdsmcert.pem /etc/pki/vdsm/libvirt-spice/server-cert.pem [root@virt-host1 ~]# cp /etc/pki/libvirt/clientcert.pem /etc/pki/libvirt/clientcert.pem.bak [root@virt-host1 ~]# cp /etc/pki/vdsm/certs/vdsmcert.pem /etc/pki/libvirt/clientcert.pem Перезапускаем службы: [root@virt-host1 ~]# systemctl restart libvirtd [root@virt-host1 ~]# systemctl restart vdsmd Проверяем срок действия сертификата [root@virt-host1 ~]# openssl x509 -noout -enddate -in /etc/pki/vdsm/certs/vdsmcert.pem Повторяем процедуру на остальных узлах с истёкшим сроком действия сертификатов. Выполняем обновления сертификатов центра управления, как описано в "Обновление сертификатов oVirt Engine" Заходим на web-консоль и проверяем работу кластера. У созданных таким образом сертификатов будет отсутствовать subject alternative name, о чём будет выдано предупреждение (через несколько часов): Certificate of host virt-host1.example.test is invalid. The certificate doesn't contain valid subject alternative name, please enroll new certificate for the host. Поэтому после восстановления доступа к web-консоли необходимо выполнить обновление сертификатов согласно официальной документации. Обновление сертификатов после истечения сроков действия при недоступном HostedEngine На практике данное решение не проверялось, но теоретически оно должно сработать. Если центр управления Engine выключен и не запускается, а в журнале journalctl на гипервизоре появляются записи libvirtd[2101]: The server certificate /etc/pki/vdsm/certs/vdsmcert.pem has expired ... systemd[1]: Failed to start Virtualization daemon Оставляем включенным один гипервизор oVirt node. Определяем время окончания действия сертификата гипервизора: [root@virt-host1 ~]# openssl x509 -noout -enddate -in /etc/pki/vdsm/certs/vdsmcert.pem Устанавливаем дату и время до окончания действия сертификата [root@virt-host1 ~]# systemctl stop chronyd [root@virt-host1 ~]# timedatectl set-time "2023-01-01 12:00:00" Перезапускаем службы [root@virt-host1 ~]# systemctl restart libvirtd [root@virt-host1 ~]# systemctl restart vdsmd Подключаемся к libvirtd через virsh и ждём, когда запустится HostedEngine [root@virt-host1 ~]# virsh -c qemu:///system?authfile=/etc/ovirt-hosted-engine/virsh_auth.conf virsh # list --all Id Name State ------------------------------ 1 HostedEngine running Выполняем обновление сертификатов по процедуре "Обновление сертификатов до истечения сроков действия" Использованные материалы Документация oVirt Проект natman Wikipedia Блог IT-KB
  •  
    ----* Создание виртуальных машин с помощью Qemu KVM (доп. ссылка 1)   Автор: Slonik  [комментарии]
     
    В статье опишу мой опыт про подготовку и запуск виртуальных машин (ВМ) с
    помощью открытых и бесплатных средств виртуализации в Linux - Qemu KVM.
    
    В качестве среды для выполнения виртуальных машин будет использоваться Fedora
    Linux 36, аналогично ВМ можно запускать в Centos 8 и выше.
    
    Для запуска ВМ понадобятся пакеты:
    
    
  • qemu-kvm (qemu-system-x86) - эмулятор
  • qemu-img - средство создания и управления виртуальными дисками
  • edk2-ovmf - образы прошивки UEFI Будет рассмотрено три типа виртуальных машин:
  • Виртуальная машина с BIOS
  • Виртуальная машина с UEFI
  • Кластер виртуальных машин с общим диском Подготовка виртуальной сети В Qemu я использую два режима подключения сети в гостевую ВМ - user networking и с использованием устройств tap. Первый режим проще, не требует root прав, но у него меньше производительность, в таком режиме не работает протокол ICMP и он не позволяет обратится к ВМ из физической сети. Второй режим предоставляет большее быстродействие при работе с сетью, его можно гибко настраивать, но он требует root права. Пользовательская виртуальная сеть Простейшую ВМ с пользовательской сетью можно запустить так: qemu-kvm \ -m 1G \ -device virtio-net-pci,netdev=lan \ -netdev user,id=lan \ -drive file=/tmp/livecd.iso,media=cdrom Ключевым параметром, который включает пользовательский режим сети это -netdev user. Такая команда запустит LiveCD внутри ВМ c 1024 МБ ОЗУ, в качестве сетевой карты будет использовано устройство Virtio. Виртуальная машина автоматически получит ip-адрес из подсети 10.0.2.0/24, шлюз - 10.0.2.2, dns-сервер - 10.0.2.3. К физическому хосту можно обратиться по адресу 10.0.2.2. ICMP пакеты через такой тип сети не проходят. Виртуальная сеть с использованием tap-устройств В данном режиме при запуске ВМ в физической системе будет создано виртуальное сетевое tap-устройство, что потребует root прав sudo qemu-kvm \ -m 1G \ -device virtio-net-pci,netdev=lan \ -netdev tap,id=lan,ifname=tap0 \ -drive file=/tmp/livecd.iso,media=cdrom При таких настройках машина запустится, но не будет иметь доступа к физической сети. Для предоставления доступа необходимо создать сетевой мост, добавить в него физический сетевой адаптер хоста и настроить скрипты добавления виртуального сетевого tap-устройства в сетевой мост. Предположим, что физический хост подключен к сети через адаптер enp3s0 и имеет адрес 192.168.1.50/24, шлюз 192.168.1.1. Удалим все сетевые настройки у адаптера enp3s0 и создадим сетевой мост с помощью Network Manager: root# nmcli connection show root# nmcli connection delete <имя подключения enp3s0> root# nmcli connection add type bridge ifname br0 con-name bridge bridge.stp false ipv4.method manual ipv4.addresses "192.168.1.50/24" ipv4.gateway 192.168.1.1 ipv6.method disabled Добавляем физический адаптер хоста в сетевой мост: nmcli con add type bridge-slave ifname enp3s0 con-name nicHost master br0 Настраиваем скрипт добавления виртуального сетевого tap-устройства к мосту - /etc/qemu-ifup: #!/bin/sh /usr/sbin/brctl addif br0 $1 /usr/sbin/ip link set dev $1 up Скрипт удаления tap-устройства из моста /etc/qemu-ifdown: #!/bin/sh /usr/sbin/ip link set dev $1 down /usr/sbin/brctl delif br0 $1 В скриптах $1 указывает на имя виртуального сетевого адаптера (tap0, tap1 и т.п.). Если потребуется разместить скрипты по другому пути, то их месторасположение можно указать в свойствах виртуального сетевого устройства с помощью директив script и downscript: sudo qemu-kvm \ -m 1G \ -device virtio-net-pci,netdev=lan \ -netdev tap,id=lan,ifname=tap0,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown \ -drive file=/tmp/livecd.iso,media=cdrom Запускаем виртуальную машину и проверяем сеть. ВМ получила адрес от DHCP сервера локальной сети. Проверяем состав сетевого моста на физическом хосте с помощью команды brctl show: В хост-системе появилось устройство tap0, и оно автоматически добавилось в сетевой мост. По-умолчанию, все виртуальные сетевые адаптеры получают MAC адрес 52:54:00:12:34:56, если потребуется запустить несколько виртуальных машин на хосте, то необходимо указать разные адреса с помощью параметра mac: sudo qemu-kvm \ -m 1G \ -device virtio-net-pci,mac=52:54:00:00:00:01,netdev=lan \ -netdev tap,id=lan,ifname=tap0,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown \ -drive file=/tmp/livecd.iso,media=cdrom Подготовка виртуальных дисков Ранее мы запускали ВМ с LiveCD. Для того чтобы установить операционную систему в виртуальную машину нам понадобится создать виртуальные диски для хранения данных. Создание виртуальных дисков qemu-img create -f qcow2 vmpath/disk.qcow2 20G Данная команда создаст "тонкий" диск в формате qcow2, объёмом 20 Гб. Если потребуется создать кластерный диск, то необходимо для него всё место выделить заранее и использовать тип диска raw: qemu-img create -f raw -o preallocation=falloc shared/shared.raw 10G Использование снимков состояния дисков Формат дисков qcow2 позволяет создавать и удалять внутри диска снимки состояний (снапшоты):
  • создание снимка: qemu-img snapshot -c snapshotName vmpath/disk.qcow2
  • список снимков: qemu-img snapshot -l vmpath/disk.qcow2
  • применить снимок (вернуть диск в состояние на момент снимка): qemu-img snapshot -a snapshotName vmpath/disk.qcow2
  • удалить снимок: qemu-img snapshot -d snapshotName vmpath/disk.qcow2 Вся работа со снимками будет производится внутри одного образа, что может потребовать времени. Другим способом создания снимков состояний является создание промежуточного файла (backing file) - при создании такого файла вся запись будет вестись в него вместо базового образа: qemu-img create -f qcow2 -F qcow2 -b vmpath/disk.qcow2 vmpath/backingDisk.qcow2 При запуске ВМ указываем в качестве диска промежуточный файл: qemu-kvm -m 1G -drive file=vmpath/backingDisk.qcow2,media=disk Чтобы откатить снапшот, достаточно перенастроить запуск на изначальный образ диска и удалить снапшот. qemu-kvm -m 1G -drive file=vmpath/disk.qcow2 ,media=disk rm vmpath/backingDisk.qcow2 Изменение первоначального образа приведёт к повреждению снапшота, поэтому после запуска ВМ с оригинальным диском все снапшоты станут бесполезными. Подключение разделов виртуального диска к хост-системе Если возникнет необходимость обратиться к файлам на виртуальном диске напрямую с хост-системы, то необходимо сначала смонтировать образ. Для того, чтобы смонтировать разделы виртуального диска к хост-системе необходимо воспользоваться утилитой qemu-nbd. 1. Загружаем модуль ядра nbd root# modprobe nbd max_part=8 2. Подключаем образ виртуального диска как сетевое блочное устройство: root# qemu-nbd --connect=/dev/nbd0 vmpath/disk.qcow2 3. Выполняем нужные нам операции с устройством: root# fdisk /dev/nbd0 -l root# mount /dev/nbd0p1 /mnt/volume/ root# umount /dev/nbd0p1 4. Отключаем устройство root# qemu-nbd --disconnect /dev/nbd0 root# rmmod nbd Запуск виртуальной машины с BIOS в Qemu KVM По-умолчанию Qemu KVM запускает виртуальные машины с BIOS, поэтому особых настроек не требуется. Готовим диск для гостевой системы: qemu-img create -f qcow2 /mnt/virtual/bios/bios.qcow2 20G Запускаем ВМ: sudo qemu-kvm \ -machine pc \ -smbios type=1,manufacturer=oVirt,product=RHEL,version=1 \ -cpu host \ -accel kvm \ -smp cpus=2,sockets=1,cores=2 \ -m 1G \ -k en-us \ -vga qxl \ -rtc base=localtime \ -netdev tap,id=lan,ifname=tap0,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown \ -device virtio-net-pci,mac=52:54:00:00:00:01,netdev=lan \ -drive file=/mnt/virtual/bios/bios.qcow2,if=virtio,media=disk,index=0 \ -drive file=/mnt/shared/linuxos.iso,media=cdrom,index=1 Параметры:
  • machine - свойства чипсета, основные это pc (совместимый со многими и ОС) и q35 (поддерживает новые устройства)
  • smbios - описание BIOS
  • cpu - тип эмулируемого ЦП, host указывает использовать как в физической системе
  • accel - тип ускорение виртуализации
  • smp - описываем кол-во виртуальных ядер ЦП и их распределение по сокетам
  • m - объём ОЗУ
  • k - раскладка клавиатуры консоли
  • vga - тип виртуального видеоадаптера
  • rtc base - настройки часов RTC
  • netdev/device и drive - описание сетевой карты и виртуальных дисков Загружаемся с CD-ROM и устанавливаем ОС. Запуск виртуальной машины с UEFI в Qemu KVM Для запуска виртуальной машины с UEFI нам потребуются прошивки из пакета edk2-ovmf. Готовим виртуальный диск для гостевой системы: qemu-img create -f qcow2 /mnt/virtual/uefi/uefi.qcow2 20G Из пакета edk2-ovmf копируем образы UEFI и NVRAM: cp /usr/share/edk2/ovmf/OVMF_CODE.fd /mnt/virtual/uefi cp /usr/share/edk2/ovmf/OVMF_VARS.fd /mnt/virtual/uefi Запускаем ВМ: sudo qemu-kvm \ -machine q35 \ -smbios type=1,manufacturer=oVirt,product=RHEL,version=1 \ -cpu host \ -accel kvm \ -smp cpus=4,sockets=1,cores=4 \ -m 4G \ -k en-us \ -vga qxl \ -device virtio-net-pci,mac=52:54:00:00:00:02,netdev=lan \ -netdev tap,id=lan,ifname=tap1,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown \ -drive if=pflash,format=raw,readonly=on,file=/mnt/virtual/uefi/OVMF_CODE.fd \ -drive if=pflash,format=raw,file=/mnt/virtual/uefi/OVMF_VARS.fd \ -drive file=/mnt/virtual/uefi/uefi.qcow2,if=virtio,media=disk \ -drive file=/mnt/shared/linuxos.iso,media=cdrom Подключаем прошивку UEFI для чтения с помощью drive if=pflash с указанием readonly=on, а также файл для хранения NVRAM, но уже в режиме записи. Загружаемся с CD-ROM и устанавливаем ОС. Запуск виртуальных машин с UEFI с общим кластерным диском в Qemu KVM Рассмотрим пример запуска двух машин, где у каждой будет свой индивидуальный диск для ОС и один общий диск для кластера. Подключать диски будем с помощью устройства -device virtio-blk-pci, оно позволяет включить совместную запись на диск с нескольких виртуальных машин c помощью параметра share-rw=on. Готовим диски для гостевых систем: qemu-img create -f qcow2 /mnt/virtual/cluster/vm1-system.qcow2 20G qemu-img create -f qcow2 /mnt/virtual/cluster/vm2-system.qcow2 20G Для кластерного диска используем формат raw и заранее резервируем место. qemu-img create -f raw -o preallocation=falloc /mnt/virtual/cluster/shared.raw 10G Копируем образы прошивки UEFI и NVRAM: cp /usr/share/edk2/ovmf/OVMF_CODE.fd /mnt/virtual/cluster cp /usr/share/edk2/ovmf/OVMF_VARS.fd /mnt/virtual/cluster/OVMF_VARS_VM1.fd cp /usr/share/edk2/ovmf/OVMF_VARS.fd /mnt/virtual/cluster/OVMF_VARS_VM2.fd Запускаем ВМ 1: sudo qemu-kvm \ -machine q35 \ -smbios type=1,manufacturer=oVirt,product=RHEL,version=1 \ -cpu host \ -accel kvm \ -smp cpus=2,sockets=1,cores=2 \ -m 2G \ -k en-us \ -vga qxl \ -device virtio-net-pci,netdev=lan,mac=52:54:00:00:00:11 \ -netdev tap,id=lan,ifname=tap11 \ -drive if=pflash,format=raw,readonly=on,file=/mnt/virtual/cluster/OVMF_CODE.fd \ -drive if=pflash,format=raw,file=/mnt/virtual/cluster/OVMF_VARS_VM1.fd \ -device virtio-blk-pci,drive=drive0,share-rw=off \ -drive file=/mnt/virtual/cluster/vm1-system.qcow2,id=drive0,format=qcow2,if=none \ -device virtio-blk-pci,drive=drive1,share-rw=on \ -drive file=/mnt/virtual/cluster/shared.raw,id=drive1,format=raw,if=none \ -drive file=/mnt/shared/linuxos.iso,media=cdrom Запускаем ВМ 2: sudo qemu-kvm \ -machine q35 \ -smbios type=1,manufacturer=oVirt,product=RHEL,version=1 \ -cpu host \ -accel kvm \ -smp cpus=2,sockets=1,cores=2 \ -m 2G \ -k en-us \ -vga qxl \ -device virtio-net-pci,netdev=lan,mac=52:54:00:00:00:12 \ -netdev tap,id=lan,ifname=tap12 \ -drive if=pflash,format=raw,readonly=on,file=/mnt/virtual/cluster/OVMF_CODE.fd \ -drive if=pflash,format=raw,file=/mnt/virtual/cluster/OVMF_VARS_VM2.fd \ -device virtio-blk-pci,drive=drive0,share-rw=off \ -drive file=/mnt/virtual/cluster/vm2-system.qcow2,id=drive0,format=qcow2,if=none \ -device virtio-blk-pci,drive=drive1,share-rw=on \ -drive file=/mnt/virtual/cluster/shared.raw,id=drive1,format=raw,if=none \ -drive file=/mnt/shared/linuxos.iso,media=cdrom Далее нужно установить ОС внутри ВМ и настроить работу с кластерным диском.
  •  
    ----* Проброс графического адаптера в виртуальную машину KVM   Автор: anon1233456  [комментарии]
     
    Для проброса графического адаптера в виртуальную машину  KVM следует указать
    при загрузке параметры ядра
    
       rd.driver.pre=vfio_pci rd.driver.pre=vfio-pciwq iommu=pt intel_iommu=on kvm.ignore_msrs=1 
    
    и добавить vfio-pci в initramfs:
    
       # as Root
       gpu="0000:06:00.0"
       aud="0000:06:00.1"
       gpu_vd="$(cat /sys/bus/pci/devices/$gpu/vendor) $(cat /sys/bus/pci/devices/$gpu/device)"
       aud_vd="$(cat /sys/bus/pci/devices/$aud/vendor) $(cat /sys/bus/pci/devices/$aud/device)"
       
       function bind_vfio {
         echo "$gpu" > "/sys/bus/pci/devices/$gpu/driver/unbind"
         echo "$aud" > "/sys/bus/pci/devices/$aud/driver/unbind"
       
       # https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-bus-pci
         echo "$gpu_vd" > /sys/bus/pci/drivers/vfio-pci/new_id
         echo "$aud_vd" > /sys/bus/pci/drivers/vfio-pci/new_id
       }
       
       function unbind_vfio {
         echo "$gpu_vd" > "/sys/bus/pci/drivers/vfio-pci/remove_id"
         echo "$aud_vd" > "/sys/bus/pci/drivers/vfio-pci/remove_id"
       
         echo 1 > "/sys/bus/pci/devices/$gpu/remove"
         echo 1 > "/sys/bus/pci/devices/$aud/remove"
         
         echo 1 > "/sys/bus/pci/rescan"
       }
       
       bind_vfio
       
       #QEMU emulator version 8.2.2 (qemu-8.2.2-1.fc40)
       NETWORK_DEVICE="virtio-net"
       MAC_ADDRESS="00:16:cb:00:21:19"
       # 0x28 - Raptor Lake fix. https://github.com/tianocore/edk2/discussions/4662
       CPU="host,host-phys-bits-limit=0x28"
       args=(
       -display gtk,grab-on-hover=on,full-screen=on
       -machine q35
       -accel kvm
       -cpu $CPU
       -m size=17338368k
       -overcommit mem-lock=off
       -smp 32,sockets=1,dies=1,clusters=1,cores=32,threads=1
       -no-user-config
       -nodefaults
       -rtc base=localtime,driftfix=slew
       -global kvm-pit.lost_tick_policy=delay
       -global ICH9-LPC.disable_s3=1
       -global ICH9-LPC.disable_s4=1
       -boot menu=off,strict=on
       -device qemu-xhci,id=xhci
       # VFIO 
       # VERY IMPORTANT PART. PLEASE NOTE THE FORMAT OF COMMAND
       # id":"pci.5","bus":"pcie.0","addr":"0x2.0x4" and "id":"pci.6","bus":"pcie.0","addr":"0x2.0x5"
       -device pcie-root-port,bus=pcie.0,id=pci_root,multifunction=true,addr=0x2
       -device '{"driver":"pcie-root-port","port":20,"chassis":5,"id":"pci.5","bus":"pcie.0","addr":"0x2.0x4"}'
       -device '{"driver":"pcie-root-port","port":21,"chassis":6,"id":"pci.6","bus":"pcie.0","addr":"0x2.0x5"}'
       -device '{"driver":"vfio-pci","host":"0000:06:00.0","id":"gpu","bus":"pci.5","addr":"0x0"}'
       -device '{"driver":"vfio-pci","host":"0000:06:00.1","id":"hdmiaudio","bus":"pci.6","addr":"0x0"}'
       #
       -drive id=HDD,if=virtio,file="$HDD",format=qcow2
       # Network
       -netdev user,id=net0
       -device "$NETWORK_DEVICE",netdev=net0,id=net0,mac="$MAC_ADDRESS"
       #
       -device virtio-serial-pci
       -usb
       -device usb-kbd
       -device usb-tablet
       -monitor stdio
       # Audio
       -audiodev   pa,id=aud1,server="/run/user/1000/pulse/native"
       -device ich9-intel-hda
       -device hda-duplex,audiodev=aud1
       #
       -device qxl-vga,vgamem_mb=128,vram_size_mb=128
       -device virtio-balloon-pci
       
       )
       qemu-system-x86_64 "${args[@]}"
       
       unbind_vfio
    
     
    ----* Подключение в BHyVe zvol-диска с другой машины   Автор: КриоМух  [комментарии]
     
    Ситуация такова: Когда-то давно в 2019 году, обратилась знакомая бухгалтер, с
    проблемой, что вирусы зашифровали все её базы 1С, хранящиеся на личном сервере,
    который ей поднял и оформил для работы по RDP - её айтишник. Когда вирус всё
    пожрал, внезапно обнаружилось, что отсутствуют резервные копии, так как они
    хранились на том же WIN-сервере, и оказались также пожранными. Более того, в
    процессе разбирательств с этой машиной, выяснилось, что там 4 диска, 2 - HDD и
    2 SSD - и при этом все они отдельными устройствами, без намёка на хоть какую-то
    реализацию зеркалирования. Айтишника этого она с позором выгнала (отказавшись с
    ним иметь дело) и обратилась ко мне.
    
    Понятно что не за восстановлением пожранного, а за организацией сервера, в
    работе и надёжности которого она бы могла быть уверена.
    
    Я как старый пользователь FreeBSD, конечно сразу ей сформировал предложение -
    эту её машину превратить в сервер на FreeBSD, а уже на нём развернуть виртуалку
    с виндой, 1С и всей этой нужной для её работы кухней.
    
    На предложение докупить ещё один ПК, чтобы был отдельной машиной для резервных
    копий - отказалась, так как женщина она во-первых бухгалтер, а во-вторых
    прижимистый бухгалтер :)
    
    Всё ей в итоге оформил в виде хоста на FreeBSD, c её ZFS-ным зеркалом на 2 HDD
    и 2 SSD, и самбой, на которую складировались ежедневные бэкапы, которые затем
    скриптом самого хоста перекладывались в samba-ресурс, доступный только на чтение.
    
    Виртуалку оформил на BHyVe'е, так как виртуалбокс  медленнен, а BHyVe и
    православный и производительней. Sparse - файлом оформил диск на HDD-пуле под
    систему в виртуалке, и SSD-пул - подключил zvol'ом как диск под базы 1С.
    
    Разворачивал BHyVe не голый, а с управлением с помощью vm-bhyve. Всё
    завелось и работало, как часы. Но через год-полтора, женщина-бухгалтер и со
    мной "рассталась", так как всё работало, а я за поддержку желал ежемесячную,
    оговорённую сумму.
    
    Никаких козней я понятное дело не строил, да и не собирался, так как честь
    IT-шную беречь должно всегда. И все актуальные копии хранилища со всеми
    доступами и чего там наворочено в её "инфраструктуре" я ей при внесении правок
    сразу высылал и при завершении сотрудничества также актуальную выдал, с
    пояснениями, что там всё что есть, все доступы и прочая-прочая, что может
    понадобиться знать любому, кто будет заниматься её сервером. Ответы на все
    вопросы так сказать. Всё.
    
    Собственно прошло 3-4 года, и вот недавно звонит она мне и говорит, что всё
    пропало. Сервак не грузится, её текущий админ не знает что со всем этим делать,
    так как с его слов "там сложная распределённая система и диски эти не может
    посмотреть". Короче сервак подох, ничего не работает, и ей главное выцарапать
    оттуда 1С базы.
    
    Получил, включил, смотрю: Действительно ничего не грузится, что-то там с uefi
    разделом, и загрузка дохнет на начальных этапах. Думаю - ничего страшного, там
    же бэкапы были, сейчас быстренько смонтирую пул, да последний достану и дело с
    концом. Загрузился с флешки, подмонтировал пул, который был HDD, под самбу -
    смотрю а бэкап последний лежит прошлогодний. Место на пуле закончилось, так как
    самбу они ещё и как файловую шару использовали и накидали туда всякого, что
    подъело весь ресурс и баз видимо 1С ещё добавилось, и бэкапы делаться просто не
    смогли, а текущий специалист, то ли не следил, то ли не знал как следить,
    короче перефразируя (надеюсь) из тех, кто: "Не следил и не проверял бэкапы, но
    теперь уже будет всегда это делать (ещё раз надеюсь)".
    
    Тогда остался один путь - получить данные непосредственно с диска в виртуалке,
    который реализован был как отдельный датасет на SSD пуле. Отцепил я значит один
    из SSD'шников и подключил к своему домашнему ПК, на котором у меня также
    FreeBSD и виртуалка BHyVe, с виндой, на случай если что-то виндовое
    потребуется. В общем вся соль этого была в подключении к BHyVe'овой машине
    диска оформленного как сырой ZFS-датасет. То есть в нём ни файлов нет, просто
    особого типа ZFS датасет.
    
    В итоге, чтобы его подключить на посторонней системе с FreeBSD, надо конечно
    первым делом ZFS-пул импортировать:
    
       zpool import -f
    
    -f нужен, так как он ругнётся что этот пул использовался на другой машине и
    вроде как может не надо его тут подключать.
    
    А после этого в 
    
       zfs list 
    
    ищем где наш датасет и объявляем его в конфигурации нашей рабочей виртуалки:
    
       disk1_type="virtio-blk"
       disk1_dev="custom"
       disk1_name="/dev/zvol/oldSSD/BHYVE/1C-BASES"
    
    И это тут так всё просто и безоблачно описано, а на деле я часа два наверное
    бодался с тем, как именно объявить zvol-овый диск в BHyVe. И в итоге
    
    
  • disk_type - должен быть virtio-blk
  • disk_dev - должен быть custom
  • disk_name - абсолютный путь к zvol'у в /dev, сперва это можно просто проверить ls'ом. Ну а дальше - ещё в самой загруженной ОСи диск не увиделся, но появился SCSI контроллер какой-то, который потребовал драйвера с диска virtio-win-0.1.229 и всё. Женщина - оплатила услуги непростого восстановления файлов, получила инструктаж на тему того, что её админ должен ей подтверждать что бэкап есть и он надёжен. Ну а она со своей стороны должна за этим бдить :)
  •  
    ----* Запуск macOS в виртуальной машине на базе QEMU/KVM (доп. ссылка 1) (доп. ссылка 2) (доп. ссылка 3)   [комментарии]
     
    Скрипт для запуска macOS в виртуальной машине (файлы с прошивками можно
    скопировать из snap sosum, proxmox или пакета ovmf из Fedora, Ubuntu или Debian).
    
    #!/bin/bash
    OSK="ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc"
    
       /usr/bin/qemu-system-x86_64 \
        -enable-kvm \
        -m 2G \
        -machine q35,accel=kvm \
        -smp 4,cores=2 \
        -cpu Penryn,vendor=GenuineIntel,kvm=on,+sse3,+sse4.2,+aes,+xsave,+avx,+xsaveopt,+xsavec,+xgetbv1,+avx2,+bmi2,+smep,+bmi1,+fma,+movbe,+invtsc \
        -device isa-applesmc,osk="$OSK" \
        -smbios type=2 \
        -object rng-random,id=rng0,filename=/dev/urandom -device virtio-rng-pci,rng=rng0 \
        -serial mon:stdio \
        -drive if=pflash,format=raw,readonly,file=./firmware/OVMF_CODE.fd \
        -drive if=pflash,format=raw,file=./firmware/OVMF_VARS-1024x768.fd \
        -device virtio-vga,virgl=on \
        -display sdl,gl=on \
        -L "$SNAP"/usr/share/seabios/ \
        -L "$SNAP"/usr/lib/ipxe/qemu/ \
        -audiodev pa,id=pa,server="/run/user/$(id -u)/pulse/native" \
        -device ich9-intel-hda -device hda-output,audiodev=pa \
        -usb -device usb-kbd -device usb-mouse \
        -netdev user,id=net0 \
        -device vmxnet3,netdev=net0,id=net0 \
        -drive id=ESP,if=virtio,format=qcow2,file=./ESP.qcow2 \
        -drive id=SystemDisk,if=virtio,file=./macos.qcow2
    
    
    Для установки macOS в виртуальной машине c использованием образа BaseSystem.img
    дополнительно нужно добавить строку:
    
        -drive id=InstallMedia,format=raw,if=virtio,file=./BaseSystem.img
    
    Для загрузки установочного образа macOS можно использовать скрипт fetch-macos.py.
    
     
    ----* vmhgfs в старых CentOS и RHEL   Автор: пох  [комментарии]
     
    Если понадобилось достучаться из CentOS 6 до хостового shared folder в VMware
    Workstation или чем-то совместимом, а стандартные способы приводят только к
    появлению загадочных мусорных сообщений в логах, что что-то где-то кого-то не
    нашло, можно поступить так:
    
    Поставить vmware-tools  от VMware (да, понадобится перл и может даже gcc).
    Ключевой момент - _целиком_. Понадобится версия 8.любая (я свою стащил из
    vsphere5.0, но вообще-то они доступны с родного сайта даже без регистрации и sms).
    
    Если в системе подключен EPEL, из которого установлен  open-vm-tools -  его
    потребуется удалить через yum erase, так как это устаревший и неработающий
    бэкпорт. Также понадобиться удалить уже установленные модули (как минимум сам
    модуль vmhgfs), полученные из других источников.
    
    В чем суть? В том, что как обычно - эру немого кино объявили deprecated, а со
    звуковым что-то пошло не так. В десятой версии VMware  перешла на новый-модный
    метод доступа к hgfs через fuse - в чем не было бы ничего плохого (дергать
    гипервизор все равно, из ядра или userspace), если бы, разумеется, всё было
    реализовано корректно. Прибить гвоздем непрошенное кэширование, игнорируя
    существующие API - норм. Исправить нельзя - "я в отпуске!" (по возвращении
    исправлено не то и не до конца, потом переисправлено, но с уровнем
    единственного штатного разработчика и качеством его кода, надеюсь, уже все ясно).
    
    Поэтому нет смысла пол-системы апгрейдить ради "поддерживаемой" таким способом мусорной версии. 
    
    Ключевой момент при этом - что устанавливать старые vmware-tools надо целиком -
    чтобы mount.vmhgfs  был той же самой (старой!) версии, что и vmhgfs.ko -
    поскольку там, внезапно, тоже stable api is nonsense - поэтому и необходимо
    удалить "опен"-vm-tools - ничего хорошего они не содержат. API самого
    гипервизора при этом не меняется (или там хорошо сохраняют обратную
    совместимость) поэтому модуль работает с любой версией.
    
    P.S. Если у вас именно штатный CentOS/RHEL, все пройдет гладко, а если что-то
    несколько отличающееся и придётся модуль пересобирать из исходников - в
    vmhgfs-only/fsutil.c в 65й строке исправьте "if" так, чтобы он всегда был
    "false" - там проверка минимальной версии, которая неправильна из-за сделанного
    rh бэкпортирования патчей, вам этот блок не нужен.
    
     
    ----* Сборка ChromiumOS из исходных текстов для запуска в QEMU (доп. ссылка 1)   [комментарии]
     
    Доступный в исходных текстах ChromiumOS главным образом отличается отсутствием
    элементов брендинга ChromeOS и компонентов DRM для просмотра защищённого контента.
    
    Для сборки вначале нужно клонировать репозиторий с инструментарием:
    
       git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
       export PATH=$PATH:$PWD/depot_tools
    
    После чего можно приступить к загрузке и сборки исходных текстов ChromiumOS
    (сборку осуществляем для целевой платформы amd64-generic, при низкой скорости
    сети или недосаточном свободном дисковом пространстве в "repo init" также можно
    указать опцию "-g minilayout" для загрузки минимально необходимого набора кода):
    
       mkdir chromiumos
       cd chromiumos
       repo init -u https://chromium.googlesource.com/chromiumos/manifest.git --repo-url https://chromium.googlesource.com/external/repo.git -g minilayout
       repo sync -j75
       cros_sdk
       export BOARD=amd64-generic
       ./setup_board --board=${BOARD}
       ./build_packages --board=${BOARD}
       ./build_image --board=${BOARD} --boot_args "earlyprintk=serial,keep console=tty0" --noenable_rootfs_verification test
       ./image_to_vm.sh --board=${BOARD} --test_image
    
    
    Для запуска окружения  ChromiumOS  можно воспользоваться командной cros_start_vm:
    cros_sdk
    
       ./bin/cros_start_vm --image_path=../build/images/${BOARD}/latest/chromiumos_qemu_image.bin --board=${BOARD}
    
    но при использовании cros_start_vm наблюдаются мешающие полноценной работе
    ограничения, такие как невозможность перенаправить графический вывод через VNC.
    Поэтому будем запускать ChromiumOS при помощи QEMU и виртуального GPU Virglrenderer.
    
    Установим сборочные зависимости (список для Ubuntu 17.10):
    
        sudo apt install autoconf libaio-dev libbluetooth-dev libbrlapi-dev \
        libbz2-dev libcap-dev libcap-ng-dev libcurl4-gnutls-dev libepoxy-dev \
        libfdt-dev \
        libgbm-dev libgles2-mesa-dev libglib2.0-dev libgtk-3-dev libibverbs-dev \
        libjpeg8-dev liblzo2-dev libncurses5-dev libnuma-dev librbd-dev librdmacm-dev \
        libsasl2-dev libsdl1.2-dev libsdl2-dev libseccomp-dev libsnappy-dev l\
        ibssh2-1-dev libspice-server-dev libspice-server1 libtool libusb-1.0-0 \
        libusb-1.0-0-dev libvde-dev libvdeplug-dev libvte-dev libxen-dev valgrind \
        xfslibs-dev xutils-dev zlib1g-dev libusbredirhost-dev usbredirserver
    
    Соберём Virglrenderer, который позволяет задействовать виртуальный GPU и
    использовать из гостевой системы графические возможности хост-системы, в том
    числе аппаратное ускорение для OpenGL. Virglrenderer является не обязательным,
    если не нужно ускорение вывода графики можно обойтись без сборки  Virglrenderer
    и убрать из строки запуска QEMU "virgl".
    
       git clone git://git.freedesktop.org/git/virglrenderer
       cd virglrenderer
       ./autogen.sh
       make -j7
       sudo make install
    
    Собираем QEMU для целевой платформы x86_64:
    
       git clone git://git.qemu-project.org/qemu.git
       mkdir -p qemu/build
       cd qemu/build
       ../configure --target-list=x86_64-softmmu --enable-gtk --with-gtkabi=3.0 \
       --enable-kvm --enable-spice --enable-usb-redir --enable-libusb --enable-virglrenderer --enable-opengl
       make -j7
       sudo make install
    
    Запускаем ChromiumOS в QEMU с использованием драйверов virtio (Linux-ядро
    хост-системы должно быть собрано с опциями CONFIG_DRM_VIRTIO,
    CONFIG_VIRT_DRIVERS и CONFIG_VIRTIO_XXXX):
    
       cd chromiumos
       /usr/local/bin/qemu-system-x86_64 \
         -enable-kvm \
         -m 2G \
         -smp 4 \
         -hda src/build/images/amd64-generic/latest/chromiumos_qemu_image.bin \
         -vga virtio \
         -net nic,model=virtio \
         -net user,hostfwd=tcp:127.0.0.1:9222-:22 \
         -usb -usbdevice keyboard \
         -usbdevice mouse \
         -device virtio-gpu-pci,virgl \
         -display gtk,gl=on
    
     
    ----* Сборка системы виртуализации crosvm из Chrome OS в обычном дистрибутиве Linux (доп. ссылка 1)   [комментарии]
     
    В Chrome/Chromium OS для изоляции приложений развивается система crosvm,
    основанная на использовании гипервизора KVM. Код  crosvm написан на языке Rust
    и примечателен наличием дополнительного уровня защиты на основе пространств
    имён, применяемого для защиты от атак на инструментарий виртуализации.
    
    Из других особенностей crosvm отмечаются встроенные средства для запуска
    Wayland-клиентов внутри изолированных окружений с выполнением композитного
    сервера на стороне основного хоста и возможность эффективного использования GPU
    из гостевых систем. Подобные возможности делают crosvm интересным решением для
    изолированного запуска графических приложений.
    
    Crosvm не привязан к Chromium OS и может быть собран и запущен в любом
    дистрибутиве Linux (протестировано в Fedora 26).
    
    Собираем ядро Linux для гостевой системы:
    
        cd ~/src
        git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
        cd linux
        git checkout v4.12
        make x86_64_defconfig
        make bzImage
        cd .. 
    
    Собираем инструментарий minijail для запуска программ в изолированных окружениях:
    
        git clone https://android.googlesource.com/platform/external/minijail
        cd minijail
        make
        cd .. 
    
    Собираем crosvm:
    
        git clone https://chromium.googlesource.com/a/chromiumos/platform/crosvm
        cd crosvm
        LIBRARY_PATH=~/src/minijail cargo build 
    
    Генерируем образ корневой ФС (rootfs) для изолированного окружения:
    
        cd ~/src/crosvm
        dd if=/dev/zero of=rootfs.ext4 bs=1K count=1M
        mkfs.ext4 rootfs.ext4
        mkdir rootfs/
        sudo mount rootfs.ext4 rootfs/
        debootstrap testing rootfs/
        sudo umount rootfs/
    
    Запускаем crosvm:
    
        LD_LIBRARY_PATH=~/src/minijail ./target/debug/crosvm run -r rootfs.ext4 --seccomp-policy-dir=./seccomp/x86_64/ ~/src/linux/arch/x86/boot/compressed/vmlinux.bin
    
     
    ----* Создание чистого openvz-контейнера на основе CentOS 6 (доп. ссылка 1)   Автор: umask  [комментарии]
     
    Разработчики OpenVZ предлагают загрузить заранее созданные шаблоны
    контейнеров, но у этих шаблонов есть недостаток - в них присутствует довольно
    много лишних пакетов, которые не хотелось бы вычищать руками. Помимо этого, в
    этих шаблонах присутствуют неподписаные пакеты, а так же репозиторий с
    пакетами-заглушками, цифровая подпись пакетов из которого не проверяется. В
    общем всё это и заставило сделать свой собственный чистый контейнер с нуля.
    Далее предлагается скрипт, который в хост-системе на основе centos6 создаёт
    чистый контейнер с это же самой ОС.
    
    Сам скрипт:
    
    
       #!/bin/bash
    
       ### exit on errors (in pipes too) and verbose execution
       set -o pipefail -e -x
       
       TMPDIR=$(mktemp -d)
       VEID=777
       DESTDIR=/vz/private/${VEID}
       
       ### veid config
       cat << _EOF_ > /etc/vz/conf/${VEID}.conf
       # This config is only valid for decent VSwap-enabled kernel
       # (version 042stab042 or later).
       
       ONBOOT="yes"
       
       # RAM
       PHYSPAGES="0:2G"
       
       # Swap
       SWAPPAGES="0:0G"
       
       # Disk quota parameters (in form of softlimit:hardlimit)
       DISKSPACE="20G:22G"
       DISKINODES="200000:220000"
       QUOTATIME="0"
       
       # CPU fair scheduler parameter
       CPUUNITS="1000"
       
       VE_ROOT="/vz/root/\\$VEID"
       VE_PRIVATE="/vz/private/\\$VEID"
       OSTEMPLATE="centos-6-secured-x86_64"
       ORIGIN_SAMPLE="basic"
       
       HOSTNAME="localhost"
       SEARCHDOMAIN=""
       NAMESERVER="8.8.8.8 8.8.4.4"
       IP_ADDRESS="10.20.30.40"
       
       CPULIMIT="100"
       CPUS="1"
       _EOF_
       
       ### stop / destroy if exists /  recreate
       vzctl stop ${VEID}
       [[ -d ${DESTDIR} ]] && rm -rf ${DESTDIR}
       mkdir -p ${DESTDIR}
       mkdir -p /vz/root/${VEID}
       
       ### init rpm db
       rpm --root ${DESTDIR} --initdb
       
       ### download packages for create base directory
       yum install -q -y yum-utils
       yumdownloader --destdir ${TMPDIR} centos-release centos-release-cr
       
       ### install base directory rpms
       TO_INSTALL=""
       for i in ${TMPDIR}/*.rpm; do
       	TO_INSTALL="${TO_INSTALL} ${i}"
       done
       
       rpm --root ${DESTDIR} -i ${TO_INSTALL}
       
       ### Save random seed
       touch ${DESTDIR}/var/lib/random-seed
       chmod 600 ${DESTDIR}/var/lib/random-seed
       dd if=/dev/urandom of=/var/lib/random-seed count=1 bs=512 2>/dev/null
       
       ### import centos pubkey
       rpm --root ${DESTDIR} --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
    
       ### install required rpms
       yum --installroot=${DESTDIR} install -q -y postfix filesystem tzdata glibc procps \\
    	coreutils rpm yum yum-utils udev openssh basesystem bash grep MAKEDEV \\
    	openssl gnupg2 logrotate rsyslog screen openssh-server openssh-clients \\
    	info ca-certificates libuuid sed vim-enhanced findutils iproute tmpwatch \\
    	wget curl patch vixie-cron sysstat htop telnet which diffutils rsync \\
    	sudo yum-cron psacct lftp tcpdump numactl git vconfig nc xz bzip2 \\
    	nscd passwd tar
    
       ### pts only in fstab
       cat << _EOF_ > ${DESTDIR}/etc/fstab
       none 	/dev/pts	devpts	gid=5,mode=620	0	0
       _EOF_
       chmod 0644 ${DESTDIR}/etc/fstab
       
       mkdir -p ${DESTDIR}/dev/pts
    
       ### create devices
       for INPATH in dev etc/udev/devices; do
    	/sbin/MAKEDEV -x -d ${DESTDIR}/${INPATH} console core fd full kmem kmsg mem null port \\
    		ptmx {p,t}ty{a,p}{0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f} random \\
    		urandom zero ram{,0,1,disk} std{in,out,err}
       done
    
       ### do not run agetty's
       sed -i 's/^ACTIVE_CONSOLES=\\(.*\\)/#ACTIVE_CONSOLES=\\1\\nACTIVE_CONSOLES=""/g' ${DESTDIR}/etc/sysconfig/init 
    
       ### run minimum services
       SERVICES="(network|crond|sshd|sysstat|snmpd|syslog|psacct|udev-post|nscd)"
       chroot ${DESTDIR} "/sbin/chkconfig" "--list" | grep -oP '^\\S+' | \\
          sort | uniq | egrep -vE "${SERVICES}" | xargs -I{} chroot ${DESTDIR} "/sbin/chkconfig" "{}" "off"
       chroot ${DESTDIR} "/sbin/chkconfig" "--list" | grep -oP '^\\S+' | \\
          sort | uniq | egrep -E "${SERVICES}" | xargs -I{} chroot ${DESTDIR} "/sbin/chkconfig" "{}" "--level" "2345" "on"
    
       ### clock/timezone
       cat << _EOF_ > ${DESTDIR}/etc/sysconfig/clock
       ZONE="Europe/Moscow"
       _EOF_
       chroot ${DESTDIR} "/usr/sbin/tzdata-update"
    
       ### make mtab actual every time
       chroot ${DESTDIR} 'rm' '-fv' '/etc/mtab'
       chroot ${DESTDIR} 'ln' '-s' '/proc/mounts' '/etc/mtab'
       
       ### cleanup
       rm -rf ${TMPDIR}
    
       ### set locale to UTF
       cat << _EOF_ > ${DESTDIR}/etc/sysconfig/i18n
       LANG="en_US.UTF-8"
       SYSFONT="latarcyrheb-sun16"
       _EOF_
       chroot ${DESTDIR} 'localedef' '-c' '-f' 'UTF-8' '-i' 'en_US' '/usr/lib/locale/en_US.utf8'
    
       ### TODO:
       ### 1. check ssh keys and delete them
       ### 2. make template.tar.gz
    
    
    
    После создания контейнера я удаляю ssh host keys и делаю дамп контейнера
    утилитой vzdump, а затем клонирую контейнеры через vzrestore. При желании можно
    сделать шаблон самостоятельно, например как написано здесь или здесь.
    
     
    ----* Сборка ядра FreeBSD для выполнения в роли паравиртуализированной гостевой системы под управлением Xen (доп. ссылка 1)   [комментарии]
     
    В репозитории http://svn.freebsd.org/base/projects/amd64_xen_pv/ доступны
    свежие версии драйверов для обеспечения работы гостевых систем FreeBSD в режиме
    паравиртуализации под управлением Xen.
    
    Для сборки паравиртуализированного ядра FreeBSD для Xen можно использовать следующую инструкцию:
    
       mkdir /dirprefix/
       mkdir /amd64_xen_pv/
       svn checkout svn://svn.freebsd.org/base/projects/amd64_xen_pv/ /amd64_xen_pv/
       cd /amd64_xen_pv/
       setenv MAKEOBJDIRPREFIX ../dirprefix/
       make -j10 -s buildkernel KERNCONF=XEN
    
    В результате ядро и необходимые модули будут размещены в директории ../dirprefix/amd64_xen_pv/sys/XEN/kernel
    
     
    ----* Настройка сетевого доступа в окружениях QEMU   Автор: Аноним  [комментарии]
     
    Заметка о том, как настроить сеть между гостевой и хостовой ОС при
    использовании QEMU. В качестве хостовой ОС Ubuntu 10.04.
    
    На стороне хоста устанавливаем uml-utilities:
    
       sudo apt-get install uml-utilities
    
    Это нужно делать только один раз. Создаем сетевой интерфейс:
    
       sudo tunctl -t qemu
    
    Вешаем на него адрес и включаем:
    
       sudo ip address add 192.168.0.1/24 dev qemu
       sudo ip link set up dev qemu
    
    
    Запускаем qemu (например):
    
       sudo qemu-system-x86_64 -hda HDD.img -cdrom FreeBSD-9.0-RC1-amd64-dvd1.iso \\
        -net nic -net tap,ifname=qemu,script=no,downscript=no -boot d
    
    Делаем простой NAT на хостовой ОС:
    
       sudo bash -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'
       sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
    
    На гостевой cистеме прописываем конфигурацию маршрута по-умолчанию и конфигурацию DNS-клиента.
    
    Еще небольшая рекомендация: запускайте qemu на десктопе под управлением утилиты
    screen. Это спасет вас, если вы вдруг решите закрыть окно терминала, в котором
    запустили qemu.
    
       screen -S qemu sudo qemu-system-x86_64 ...
    
    Потом делаем detach (^D) и закрываем окно терминала.
    
     
    ----* Установка XCP XenAPI в Ubuntu 11.10 или Debian GNU/Linux (доп. ссылка 1)   [комментарии]
     
    Благодаря портированию XCP XenAPI для Debian и Ubuntu Linux у пользователей
    данных дистрибутивов появилась возможность создания сервера виртуализации,
    функционально эквивалентного стандартному дистрибутиву XCP на базе CentOS.
    
    В процессе развертывания Xen хоста следует не поддастся искушению установки
    пакета с ядром Linux, оканчивающегося на "-virtual". Такие ядра в Ubuntu/Debian
    оптимизированы для использования внутри гостевых систем и не сконфигурированы
    для использования в роли Dom0.
    
    
    После установки XAPI будут запущены сервисы, использующие сетевые порты 80 и
    443. Поэтому важно проследить, чтобы на текущем сервере до этого не был запущен
    http-сервер или настроить раздельный запуск XAPI на другом IP. При
    использовании VPN и сетевого интерфейса tun0, наблюдается ряд проблем, которые
    могут привести к невозможности запуска XAPI.
    
    Установка XAPI
    
    Устанавливаем компоненты XAPI из специального PPA-репозитория ubuntu-xen-org.
    Добавляем в /etc/apt/sources.list
    
       deb http://ppa.launchpad.net/ubuntu-xen-org/xcp-unstable/ubuntu oneiric main
       deb-src http://ppa.launchpad.net/ubuntu-xen-org/xcp-unstable/ubuntu oneiric main
    
    или подключаем репозиторий для Debian:
    
       apt-get install curl 
       echo "deb http://downloads.xen.org/XCP/debian/repo/debian unstable main" > /etc/apt/sources.list.d/kronos.list 
       echo "deb-src http://downloads.xen.org/XCP/debian/repo/debian unstable main" >> /etc/apt/sources.list.d/kronos.list 
       wget --quiet -O - http://downloads.xen.org/XCP/debian/xcp.gpg.key | apt-key add - 
    
    Устанавливаем xapi:
    
       apt-get update
       apt-get install xcp-xapi
    
    
    Вариант сборки свежей версии инструментария XCP из исходных текстов с
    использованием xapi-autobuilder.
    
    Устанавливаем необходимые для сборки компоненты:
    
       apt-get install pbuilder debhelper dh-ocaml dh-autoreconf cdebootstrap python-debian mercurial git
    
       wget http://downloads.xen.org/XCP/debian/blktap-dkms_0.1_all.deb
       dpkg -i blktap-dkms_0.1_all.deb
    
    
    Клонируем Git-репозиторий xapi-autobuilder и выполняем сборку:
    
       git clone https://github.com/jonludlam/xapi-autobuilder.git
       cd xapi-autobuilder
       make clean ; make
    
    в итоге будут подготовлены необходимые для установки в  Debian пакеты, свежие
    версии которых также можно загрузить командой:
    
       wget -r -l1 --no-parent -nd http://downloads.xen.org/XCP/debian/latest/
       rm  index.html*
    
    
    
    Настройка XAPI
    
    Активируем по умолчанию опцию загрузки Xen в Grub:
    
       sed -i 's/GRUB_DEFAULT=""/GRUB_DEFAULT="Xen 4.1-amd64"/' /etc/default/grub
       update-grub
    
    Настраиваем параметры сети
    
    В /etc/network/interfaces добавляем запуск интерфейсе xenbr0:
    
       auto lo xenbr0
    
       iface xenbr0 inet dhcp
            bridge_ports eth0 
    
    Вместо "dhcp" при необходимости можно прописать статический IP.
    
    
    Настраиваем содержимое файла xensource-inventory (в скрипте ниже
    подразумевается, что корневой раздел /dev/sda1, а управляющий сетевой интерфейс
    xenbr0). Для генерации xensource-inventory  запускаем простой shell-скрипт:
    
       control_domain=`uuidgen`
       installation=`uuidgen`
    
       cat > /etc/xensource-inventory << EOF
       CURRENT_INTERFACES='xenbr0'
       BUILD_NUMBER='0'
       CONTROL_DOMAIN_UUID='${control_domain}' 
       INSTALLATION_UUID='${installation}'
       MANAGEMENT_INTERFACE='xenbr0'
       PRIMARY_DISK='/dev/sda1'
       EOF
    
    Перезагружаем систему
    
       reboot
    
    
    
    Использование XCP
    
    Убедимся, что xapi запущен
    
       service xapi status
    
    если нет, то запустим его командой
    
       service xapi start
    
    Добавим к переменноё окружения PATH путь к исполняемым файлам xapi:
    
       export PATH=$PATH:/usr/lib/xen-common/xapi/bin
    
    Создадим репозиторий хранения. Рекомендуется использовать NFS или EXT, если в
    системе есть свободное блочное устройство.
    
    Для NFS (в переменную SR будет записан идентификатор хранилища):
    
       SR=`xe sr-create type=nfs name-label=nfs device-config:server=<nfs server> device-config:serverpath=<path on server>`
    
    Для незанятого блочного устройства /dev/sda3  (внимание, указанный раздел будет отформатирован !)
    
    
       SR=`xe sr-create type=ext device-config:device=/dev/sda3 name-label=ext` 
    
    Свяжем созданное хранилище с пулом:
    
    
       POOL=`xe pool-list --minimal`
       xe pool-param-set uuid=$POOL default-SR=$SR
    
    
    
    Решение проблемы с памятью для Dom0
    
    В штатном ядре Ubuntu 11.10 наблюдается проблема с выделением недостаточного
    объема памяти для Dom0. Данная проблема решена в ядре 3.2. В качестве обходного
    пути решения, можно вручную увеличить размер выделенной для нужд Dom0 памяти
    (посмотреть текущее значением можно через "cat /proc/meminfo" ).
    
    Находим uuid идентификатор Dom0:
    
       xe vm-list
    
       uuid ( RO)           : f5d0039b-1138-4635-c153-6203bfdc330f
         name-label ( RW): Control domain on host: piggy
         power-state ( RO): running
    
    Вручную назначаем нижний и верхний лимит памяти:
    
       xe vm-param-set uuid=f5d0039b-1138-4635-c153-6203bfdc330f memory-dynamic-max=2GiB
       xe vm-param-set uuid=f5d0039b-1138-4635-c153-6203bfdc330f memory-dynamic-min=2GiB
    
    
    Установка гостевой системы с Linux
    
    Находим шаблон для установки интересующего дистрибутива:
    
       xe template-list
    
    Ниже представленный скрипт позволяет автоматизировать выполнение установки.
    Скрипт следует запускать из локальной системы (Dom0), но его можно легко
    модифицировать для организации удалённой установки с другого хоста. На
    завершающем этапе работы скрипта будет произведён запуск виртуальной машины для
    выполнения финального этапа установки.
    
    В скрипте может понадобиться поменять следующие переменные:
    
       "vm-label" - метка для ссылки на VM из  Dom0;
       "hostname" - имя хоста;
       "domain" - локальный домен
    
    В качестве шаблона для установки выбран Ubuntu Lucid Lynx 10.04 (64-bit)
    
    
       #!/bin/bash
       set -e
       set -x
    
       template=`xe template-list name-label="Ubuntu Lucid Lynx 10.04 (64-bit)" --minimal`
       vm=`xe vm-install template=$template new-name-label=vm-label`
       network=`xe network-list bridge=xenbr0 --minimal`
       vif=`xe vif-create vm-uuid=$vm network-uuid=$network device=0`
    
       xe vm-param-set uuid=$vm other-config:install- repository=http://archive.ubuntu.com/ubuntu
       xe vm-param-set uuid=$vm PV-args="auto-install/enable=true interface=auto netcfg/dhcp_timeout=600 hostname=vm-host-name domain=mydomain.is.best"
    
       xe vm-start uuid=$vm
    
    
    Для завершения установки следует подключиться к виртуальной машине, например, через "xe console"
    Перед этим следует запустить демон  xapissl:
    
       service start xapissl
    
    Список активных консолей VM можно посмотреть командой:
    
       xe console-list
    
    Выбрав нужный vm-uuid выполняем:
    
       xe console uuid=593c6788-1ddc-e7d7-c6b1-0de0778c78b7
    
    Если что-то пошло не так удалить установленную виртуальную машину можно командой:
    
       xe vm-uninstall name-label=vm-label  --multiple
    
    
    
    Установка гостевой системы с Windows
    
    Для установки Windows необходимо наличие установочного iso-образа, который
    может быть импортирован с другой машины по NFS:
    
       xe-mount-iso-sr nfs-server:/path/to/isos
    
    Создаём виртуальную машину с Windows:
    
       xe vm-install template=Windows\ 7\ \(32-bit\) new-name-label=windows
       xe vm-cd-add vm=windows cd-name=win7.iso device=3
       xe vm-start vm=windows
    
    Для обеспечения работы сети выполняем создание сетевого моста:
     
       brctl addbr xenbr0
       brctl addif xenbr0 eth0
    
    
    Поднимаем IP на интерфейсе сетевого бриджа вместо физического интерфейса. После чего запускаем:
    
       xe pif-scan
    
    Устанавливаем в Window паравиртуальные драйверы, которые можно загрузить следующим образом:
    
       wget http://downloads.xen.org/XCP/debian/xs-tools-5.9.960.iso
       mv xs-tools-5.9.960.iso /usr/lib/xen-common/xapi/packages/iso
    
     
    ----* Тестирование во FreeBSD системы виртуализации BSD Hypervisor (BHyVe) (доп. ссылка 1) (доп. ссылка 2)   [комментарии]
     
    Разработчики FreeBSD приглашают принять участие в тестировании гипервизора
    BSD Hypervisor (BHyVe), открытого в этом году компанией NetApp. Гипервизор
    BHyVe обладает прекрасной производительностью, но пока не входит в состав
    основной кодовой базы FreeBSD и нуждается в дополнительном тестировании.
    
    Для работы BHyVe требуется наличие новых CPU Intel Core i3, i5 и i7,
    поддерживающих механизм виртуализации VT-x и  работу со вложенными страницами
    памяти (EPT - Extended Page Tables). Опционально для проброса PCI-устройств в
    госетвые окружения может быть задействована технология VT-d (Direct Device
    Attach). Проверить наличие VY-x можно просмотрев  флаги в секции "Features" в
    выводе dmesg, в списке должен присутствовать флаг VMX.
    
    В качестве гостевой системы пока может работать только FreeBSD. Созданные в
    рамках проекта паравиртуальные драйверы для ускорения работы с устройствами
    хранения и сетевого доступа (virtio, if_vtnet, virtio_pci, virtio_blk) в
    дальнейшем могут быть адаптированы для работы гостевых систем совместно с
    другими системами виртуализации.
    
    Подготовка хост-окружения
    
    Пользователи FreeBSD-CURRENT могут загрузить необходимые патчи из специального репозитория:
    
       svn co http://svn.freebsd.org/base/projects/bhyve /usr/src/
    
    Для FreeBSD 9.0BETA3 можно использовать ревизию 225769 из этого же SVN-репозитория BHyVe. 
    
    Устанавливаем необходимые порты:
    
       pkg_add -r subversion
       pkg_add -r binutils
       pkg_add -r curl
       rehash
    
    Загружаем исходные тексты из SVN (грузим ревизию 225769):
    
       svn co http://svn.freebsd.org/base/projects/bhyve@225769 /usr/src/
    
    Пересобираем ядро и перезагружаем систему:
    
       cd /usr/src
       make buildkernel KERNCONF=GENERIC
       make installkernel KERNCONF=GENERIC
       reboot
    
    После перезагрузки необходимо загрузить модуль ядра vmm.ko:
    
       kldload vmm
    
    Для управления BHyVe необходимо установить несколько вспомогательных утилит:
    /usr/sbin/bhyve, /usr/sbin/bhyveload и /usr/sbin/vmmctl, а также библиотеку
    /usr/lib/libvmmapi.*. Уже собранные данные компоненты можно загрузить здесь,
    для установки следует запустить скрипт cpinstall.sh.
    
    Для сборки из исходных текстов можно использовать примерно такие команды:
    
       cd /usr/src/
       make buildworld
       mkdir /usr/jail/
       make installworld DESTDIR=/usr/jail/
       cp /usr/jail/usr/sbin/bhyve* /usr/sbin/
       cp /usr/jail/usr/sbin/vmm* /usr/sbin/
       cp /usr/jail/usr/lib/libvmmapi* /usr/lib/
       rehash
    
    Правим /boot/loader.conf. Отключаем  вывод отладочных предупреждений и изменяем
    лимит памяти до 4 Гб для системы с 8 Гб ОЗУ (остальные 4 Гб будут отданы
    гостевым системам):
    
       debug.witness.watch="0"
       hw.physmem="0x100000000"
    
    После перезагрузки вывод dmesg для  системы с 8 Гб ОЗУ выглядит примерно так:
    
       real memory  = 8589934592 (8192 MB)
       avail memory = 3021811712 (2881 MB)
    
    
    Подготовка гостевой системы:
    
    Для упрощения тестирования подготовлен уже сконфигурированный образ гостевой
    системы, который  можно загрузить и установить выполнив:
    
       cd /usr/share/
       curl -O http://people.freebsd.org/~neel/bhyve/vm1.tar.gz
       gunzip vm1.tar.gz
       tar -xf vm1.tar
    
    Данный образ содержит скрипт запуска и образ коревой ФС, размером 300 Мб
    (/usr/share/vm1/boot/kernel/mdroot). При загрузке создаётся два  virtio-устройства:
    
        vtnet0: виртуальный сетевой интерфейс, привязанный к интерфейсу tap0 на стороне хост-системы
        vtbd0: виртуальной блочное устройство, использующее 32 Гб дисковый образ /usr/share/vm1/diskdev
    
    
    Скрипт /usr/share/vm1/vmprep.sh предназначен для подготовки хост-системы для
    использования BHyVe, включая загрузку модуля ядра vmm.ko и настройку сети
    (вместо em0 следует указать текущий сетевой адаптер).
    
       #!/bin/sh
       kldload vmm
       kldload if_tap
       ifconfig tap0 create
       kldload bridgestp
       kldload if_bridge
       ifconfig bridge0 create
       ifconfig bridge0 addm em0
       ifconfig bridge0 addm tap0
       ifconfig bridge0 up
       ifconfig tap0 up
    
    
    Запуск гостевой системы в среде виртуализации:
    
    Выполняем скрипт конфигурации хост-системы и запускаем гостевое окружение vm1:
    
       cd /usr/share/vm1/
       sh vmprep.sh
       sh vmrun.sh vm1
    
    Если не удаётся загрузить модуль vmm.ko на экран будет выведена примерно такая ошибка:
    
       Launching virtual machine "vm1" with 768MB memory below 4GB and 2048MB memory above 4GB ...
      vm_create: No such file or directory
    
    В случае успеха будет отображён процесс загрузки FreeBSD:
    
    
       Launching virtual machine "vm1" with 768MB memory below 4GB and  2048MB memory above 4GB ...
       Consoles: userboot  
    
       FreeBSD/amd64 User boot, Revision 1.1
       (neel@freebsd.org, Sun Sep 25 22:19:14 PDT 2011)
       Loading /boot/defaults/loader.conf 
       /boot//kernel/kernel text=0x41e94f data=0x57ac0+0x273590 syms=[0x8+0x737b8+0x8+0x6abe3]
       /boot//kernel/virtio.ko size 0x4ad8 at 0xbc8000
       /boot//kernel/if_vtnet.ko size 0xac80 at 0xbcd000
       /boot//kernel/virtio_pci.ko size 0x56c0 at 0xbd8000
       /boot//kernel/virtio_blk.ko size 0x4f60 at 0xbde000
       ....
    
    Если используемый в системе процессор не содержит возможностей,  необходимых
    для работы BHyVe, будет выведен примерно такой текст ошибки:
    
       ...
       AMD Features=0x20100800<SYSCALL,NX,LM>
       AMD Features2=0x1<LAHF>
       kldload vmm.ko
       vmx_init: processor does not support desired primary processor-based controls
       module_register_init: MOD_LOAD (vmm, 0xffffffff816127a0, 0) error 22
    
    Тестовая гостевая система сконфигурирована с пустым паролем для пользователя
    root. После входа следует настроить параметры сети указав IP в ручную через
    команду ifconfig или получив адрес по DHCP, запустив "dhclient vtnet0".
    
    Для остановки виртуальной машины нужно перезагрузить гостевое окружение, нажать
    ESC при появлении экрана загрузки и набрать "quit" в приглашении загрузчика.
    
     
    ----* Опыт восстановления работы zones в Solaris 11 Express/OpenSolaris (доп. ссылка 1)   Автор: sergm  [комментарии]
     
    После скоропостижной гибели жесткого диска с лежащими на нем зонами, наступило
    время восстановить их из бекапа и запустить. Казалось, тривиальная процедура,
    отрепетированная на тестовых системах (но не тех, где лежали зоны - это
    важно) отняла много времени и поставила несколько вопросов, ответы на которые
    еще придется поискать.
    
    Восстанавливаем зону из бекапа:
    
       # zfs send -R backup/zone/develop@rep201108250419 | zfs receive -F vol01/ zone/develop@rep201108250419
    
    Стартуем зону и наблюдаем странное:
    
       # zoneadm -z develop boot
    
       zone 'develop': ERROR: no active dataset.
       zone 'develop':
       zoneadm: zone 'develop': call to zoneadmd failed
    
    Ошибка явно говорит о том, что у нас что-то не в порядке со свойствами датасета.
    
    Начинаем осмотр датасета
    
    Чтобы было с чем сравнивать, я создал и запустил тестовую зону, свойства ее
    файловых систем и брал за эталон.
    
    Тестовая зона создается примерно так:
    
        # zonecfg -z testzone
    
        testzone: No such zone configured
        Use&#8217;create&#8217; to begin configuring a new zone.
        zonecfg:testzone>create
        zonecfg:testzone>set zonepath=/vol01/zone/testzone
        zonecfg:testzone>set autoboot=false
        zonecfg:testzone>add net
        zonecfg:testzone:net>set physical=e1000g4
        zonecfg:testzone:net>set address=192.168.0.24/24
        zonecfg:testzone:net>end
        zonecfg:testzone>verify
        zonecfg:testzone>commit
        zonecfg:testzone>exit
    
        # zoneadm -z testzone install
        ...
    
        # zoneadm -z testzone boot
    
    При инсталляции в OpenSolaris/Solaris 11 создаются три датасета (по адресу zonepath):
    
        # zfs list | grep vol01/zone/testzone
    
        NAME
        vol01/zone/testzone
        vol01/zone/testzone/ROOT
        vol01/zone/testzone/ROOT/zbe
    
    Лечение
    
        Смотрим полный список свойств датасетов исправной и сломанной зон и сравниваем их:
        
       # zfs get all vol01/zone/testzone
    
        (сдесь должен быть очень большой вывод, который я пропустил и самое интересное из которого можно увидеть ниже)
    
        # zfs get all vol01/zone/testzone/ROOT
        ...
        # zfs get all vol01/zone/testzone/ROOT/zbe
        ...
        # zfs get all vol01/zone/develop
        ...
        # zfs get all vol01/zone/develop/ROOT
        ...
        # zfs get all vol01/zone/develop/ROOT/zbe
    
        ...
    
    Наблюдаем основную разницу в данных свойствах датасета:
    
       # zfs get zoned,canmount,mountpoint,org.opensolaris.libbe:parentbe,org.opensolaris.libbe:active vol01/zone/testzone/ROOT/zbe
    
        NAME    PROPERTY    VALUE    SOURCE
    
        vol01/zone/testzone/ROOT/zbe  zoned on inherited from vol01/zone/testzone/ROOT
        vol01/zone/testzone/ROOT/zbe  canmount noauto  local
        vol01/zone/testzone/ROOT/zbe  mountpoint legacy inherited from vol01/zone/testzone/ROOT
        vol01/zone/testzone/ROOT/zbe  org.opensolaris.libbe:parentbe  2aadf62d-9560-e14b-c36a-f9136fbce6e9  local
        vol01/zone/testzone/ROOT/zbe  org.opensolaris.libbe:active on  local
    
       # zfs get zoned,canmount,mountpoint,org.opensolaris.libbe:parentbe,org.opensolaris.libbe:active vol01/zone/develop/ROOT/zbe
    
        NAME    PROPERTY    VALUE    SOURCE
    
        vol01/zone/develop/ROOT/zbe  zoned off default
        vol01/zone/develop/ROOT/zbe  canmount on default
        vol01/zone/develop/ROOT/zbe  mountpoint /vol01/zone/develop/ROOT/zbe  default
        vol01/zone/develop/ROOT/zbe  org.opensolaris.libbe:parentbe - -
        vol01/zone/develop/ROOT/zbe  org.opensolaris.libbe:active - -
    
    
    Исправляем, чтобы было нормально:
    
        # zfs set zoned=on vol01/zone/develop/ROOT/zbe
        # zfs set canmount=noauto vol01/zone/develop/ROOT/zbe
        # zfs set mountpoint=legacy vol01/zone/develop/ROOT/zbe
        # zfs set org.opensolaris.libbe:parentbe=2aadf62d-9860-e14b-c36a-f9106fbce6e9 vol01/zone/develop/ROOT/zbe
        # zfs set org.opensolaris.libbe:active=on vol01/zone/develop/ROOT/zbe
    
    Аналогично, правим vol01/zone/develop/ROOT после сравнения с работающей зоной:
    
       # zfs get zoned,canmount,mountpoint,org.opensolaris.libbe:parentbe,org.opensolaris.libbe:active vol01/zone/testzone/ROOT
    
        NAME    PROPERTY    VALUE    SOURCE
        vol01/zone/testzone/ROOT  zoned on local
        vol01/zone/testzone/ROOT  canmount on default
        vol01/zone/testzone/ROOT  mountpoint legacy local
        vol01/zone/testzone/ROOT  org.opensolaris.libbe:parentbe - -
        vol01/zone/testzone/ROOT  org.opensolaris.libbe:active  - -
    
       # zfs get zoned,canmount,mountpoint,org.opensolaris.libbe:parentbe,org.opensolaris.libbe:active vol01/zone/develop/ROOT
    
        NAME    PROPERTY    VALUE    SOURCE
        vol01/zone/develop/ROOT  zoned off default
        vol01/zone/develop/ROOT  canmount on default
        vol01/zone/develop/ROOT  mountpoint  /vol01/zone/develop/ROOT     default
        vol01/zone/develop/ROOT  org.opensolaris.libbe:parentbe - -
        vol01/zone/develop/ROOT  org.opensolaris.libbe:active - -
    
       # zfs set zoned=on vol01/zone/develop/ROOT
       # zfs set canmount=on vol01/zone/develop/ROOT
    
    После этого у нас все хорошо: свойства датасетов практически идентичны.
    
        # zlogin -C develop
    
        [Connected to zone 'develop' console]
        [NOTICE: Zone booting up]
        SunOS Release 5.11 Version snv_134 64-bit
        Copyright 1983-2010 Sun Microsystems, Inc.  All rights reserved.
        Use is subject to license terms.
        Hostname: develop
        Reading ZFS config: done.
        Mounting ZFS filesystems: (5/5)
    
        develop console login: mike
        Password:
        Last login: Mon Aug 2 06:41:54 from nostalgia
        Sun Microsystems Inc.   SunOS 5.11      snv_134 February 2010
        (mike@develop)$ su
        Password:
        Aug 27 15:04:13 develop su: &#8216;su root&#8217; succeeded for mike on /dev/console
        (root@develop)# svcs -xv
        (root@develop)#
    
    Вместо послесловия
    
    Если у зоны были смонтированы  из глобальной зоны файловые системы через lofs,
    будет такой казус - зона загрузиться, но локальные файловые системы не будут
    смонтированы, сервис filesystem/local:default перейдет в состояние maintenance
    с ошибкой 262 в логах:
       /usr/bin/zfs mount -a failed: cannot mount local filesystem.
    
    Проблему можно решить экспортировав и затем импортировав зону
    
       # zoneadm -z webapp detach
       # zoneadm -z webapp attach
    
    После этого все будет работать нормально.
    
     
    ----* Использование PaaS-платформы CloudFoundry в Ubuntu 11.10 (доп. ссылка 1) (доп. ссылка 2)   [обсудить]
     
    В universe-репозиторий  Ubuntu 11.10 будут входить пакеты с реализацией
    поддержки серверной и клиентской части PaaS-платформы (Platform as a Service) [[http://www.opennet.dev/opennews/art.shtml?num=30241
    CloudFoundry]], развиваемой компанией VMware и доступной в исходных текстах под
    лицензией Apache.
    
    Платформа позволяет сформировать инфраструктуру для выполнения в облачных
    окружениях конечных приложений на Java (Spring), Grails, Ruby (Rails, Sinatra),
    JavaScript (Node.js), Scala и других языках, работающих поверх JVM. Из СУБД
    поддерживаются СУБД MySQL, Redis и MongoDB. PaaS-платформа, в отличие от IaaS,
    работает на более высоком уровне, чем выполнение готовых образов операционных
    систем, избавляя потребителя от необходимости обслуживания ОС и системных
    компонентов, таких как СУБД, языки программирования, программные фреймворки и
    т.п. В PaaS от пользователя требуется только загрузка приложения, которое будет
    запущено в готовом окружении, предоставляемом платформой.
    
    
    Устанавливаем необходимые серверные пакеты из отдельного PPA-репозитория:
    
       sudo apt-add-repository ppa:cloudfoundry/ppa
       sudo apt-get update
       sudo apt-get install cloudfoundry-server
    
    В процессе установки потребуется ответить на несколько вопросов debconf, таких как пароль к MySQL.
    
    Устанавливаем клиентские пакеты для тестирования сервера:
    
       sudo apt-get install cloudfoundry-client
    
    В итоге имеем сервер "vcap" и клиент "vmc".
    
    Настройка
    
    По умолчанию vmc-клиент настроен для работы с внешним сервисом
    CloudFoundry.com. Для того, чтобы обеспечить его работу с локальным сервером
    потребуется настроить сопутствующие локальных службы.
    
    Во первых требуется обеспечить автоматическое сопоставление для выполняемых
    приложений IP-адреса cloud-окружения с доменным именем. Самым типичным способом
    является использование готовых DNS-сервисов, таких как DynDNS.com, настроить
    автоматическую отправку обновлений на сервис SynDNS.com можно запустив:
    
       dpkg-reconfigure cloudfoundry-server
    
    
    В более простом случае, для проведения экспериментов можно обойтись правкой
    /etc/hosts на стороне клиента и сервера.
    
    Смотрим внешний IP-адрес сервера. Если сервер запущен не на локальной машине, а
    в сервисе Amazon EC2 адрес можно посмотреть через обращение к API Amazon командой:
    
       wget -q -O- http://169.254.169.254/latest/meta-data/public-ipv4
       174.129.119.101
    
    Соответственно, в /etc/hosts на сервере и клиентских машинах добавляем
    управляющий хост api.vcap.me, а также хост для тестового приложения (в нашем
    случае приложение будет называться testing123):
    
       echo "174.129.119.101  api.vcap.me testing123.vcap.me" | sudo tee -a /etc/hosts
    
    Привязываем vmc-клиент к серверу vcap (CloudFoundry):
    
       vmc target api.vcap.me
    
       Succesfully targeted to [http://api.vcap.me]
    
    Добавляем на сервер нового пользователя:
    
       vmc add-user 
    
       Email: test@example.com
       Password: ********
       Verify Password: ********
       Creating New User: OK
       Successfully logged into [http://api.vcap.me]
    
    Заходим на сервер:
    
       vmc login 
    
       Email: test@example.com
       Password: ********
       Successfully logged into [http://api.vcap.me]
    
    
    Размещаем своё приложение на сервере. В качестве примера, загрузим простую
    программу на языке Ruby, использующую фреймворк Sinatra. Примеры можно найти в
    директории /usr/share/doc/ruby-vmc/examples.
    
    Переходим в директорию с приложением:
       cd /usr/share/doc/ruby-vmc/examples/ruby/hello_env
    
    Копируем его на сервер:
    
       vmc push
    
       Would you like to deploy from the current directory? [Yn]: y
       Application Name: testing123
       Application Deployed URL: 'testing123.vcap.me'? 
       Detected a Sinatra Application, is this correct? [Yn]: y
       Memory Reservation [Default:128M] (64M, 128M, 256M, 512M, 1G or 2G) 
       Creating Application: OK
       Would you like to bind any services to 'testing123'? [yN]: n
       Uploading Application:
         Checking for available resources: OK
         Packing application: OK
         Uploading (0K): OK 
         Push Status: OK
         Staging Application: OK
         Starting Application: OK
    
    Все готово! Теперь можно открыть в браузере http://testing123.vcap.me/ и
    насладиться результатом работы загруженной программы.
    
    
    Пример развертывания приложения в сервисе CloudFoundry.com
    
    Подкоючаем vmc-клиент к сервису CloudFoundry.com:
    
       vmc target https://api.cloudfoundry.com
    
       Succesfully targeted to [https://api.cloudfoundry.com]
    
    Входим, предварительно зарегистрировавшись на сайте CloudFoundry.com:
    
       vmc login
       Email: test@example.com
       Password: **********
       Successfully logged into [https://api.cloudfoundry.com]
    
    Размещаем NodeJS-приложение:
    
       cd /usr/share/doc/ruby-vmc/examples/nodejs/hello_env
       vmc push
    
       Would you like to deploy from the current directory? [Yn]: y
       Application Name: example102
       Application Deployed URL: 'example102.cloudfoundry.com'? 
       Detected a Node.js Application, is this correct? [Yn]: y
       Memory Reservation [Default:64M] (64M, 128M, 256M, 512M or 1G) 64M
       Creating Application: OK
       Would you like to bind any services to 'example102'? [yN]: n
       Uploading Application:
         Checking for available resources: OK
         Packing application: OK
         Uploading (0K): OK   
       Push Status: OK
       Staging Application: OK
       Starting Application: OK 
    
    Открываем в браузере http://example102.cloudfoundry.com/ и видим результат работы
    
    
    Размещаем программу на Java:
    
    Переходим в директорию с примером:
    
       cd /usr/share/doc/ruby-vmc/examples/springjava/hello_env
    
    Собираем JAR-архив:
    
       sudo apt-get install openjdk-6-jdk maven2
       ...
       cd $HOME
       cp -r /usr/share/doc/ruby-vmc/examples/springjava .
       cd springjava/hello_env/
       mvn clean package
       ...
       cd target
    
    Загружаем на сервер:
    
       vmc push
    
       Would you like to deploy from the current directory? [Yn]: y
       Application Name: example103
       Application Deployed URL: 'example103.cloudfoundry.com'?  
       Detected a Java Web Application, is this correct? [Yn]: y
       Memory Reservation [Default:512M] (64M, 128M, 256M, 512M or 1G) 512M
       Creating Application: OK
       Would you like to bind any services to 'example103'? [yN]: n
       Uploading Application:
         Checking for available resources: OK
         Packing application: OK
         Uploading (4K): OK   
       Push Status: OK
       Staging Application: OK 
       Starting Application: OK
    
    Открываем в браузере http://example103.cloudfoundry.com/.
    
    Размещаем более сложное готовое web-приложение Drawbridge, требующее для
    своей работы СУБД MySQL (параметры подключаемого сервиса mysql-4a958 задаются
    отдельно, в web-интерфейсе cloudfoundry.com):
    
       cd $HOME
       bzr branch lp:~kirkland/+junk/drawbridge   
       cd drawbridge  
    
       vmc push
    
       Would you like to deploy from the current directory? [Yn]: y
       Application Name: example104
       Application Deployed URL: 'example104.cloudfoundry.com'? 
       Detected a Node.js Application, is this correct? [Yn]: y
       Memory Reservation [Default:64M] (64M, 128M, 256M or 512M) 128M
       Creating Application: OK
       Would you like to bind any services to 'example104'? [yN]: y
       Would you like to use an existing provisioned service [yN]? n
       The following system services are available:
          1. mongodb
          2. mysql
          3. redis
       Please select one you wish to provision: 2
       Specify the name of the service [mysql-4a958]: 
       Creating Service: OK
       Binding Service: OK
       Uploading Application:
         Checking for available resources: OK
         Processing resources: OK
         Packing application: OK
         Uploading (77K): OK   
       Push Status: OK
       Staging Application: OK 
    Starting Application: OK
    
    Открываем http://example104.cloudfoundry.com 
    
    Просмотр размещенных приложений и доступных сервисов.
    
    Выводим список приложений:
    
       vmc apps 
    
       | Application | #  | Health  | URLS | Services    |
       | example102 | 1  | RUNNING | example102.cloudfoundry.com | |
       | example103 | 1  | RUNNING | example103.cloudfoundry.com | |
       | example101 | 1  | RUNNING | example101.cloudfoundry.com | |
       | example104 | 1  | RUNNING | example104.cloudfoundry.com | mysql-4a958 |
    
    Выводим список доступных сервисов:
    
       vmc services 
    
       | Service | Version | Description                   |
       | redis   | 2.2     | Redis key-value store service |
       | mongodb | 1.8     | MongoDB NoSQL store           |
       | mysql   | 5.1     | MySQL database service        |
    
       == Provisioned Services ==
    
       | Name        | Service |
       | mysql-4a958 | mysql   |
       | mysql-5894b | mysql   |
    
    
    Выводим список доступных фреймворков:
    
       vmc frameworks 
    
       | Name    |
       | rails3  |
       | sinatra |
       | lift    |
       | node    |
       | grails  |
       | spring  |
    
    
    Изменение выделенных для приложения ресурсов
    
    Увеличение доступной памяти:
    
       vmc mem example101
    
       Update Memory Reservation? [Current:128M] (64M, 128M, 256M or 512M) 512M
       Updating Memory Reservation to 512M: OK
       Stopping Application: OK
       Staging Application:  OK 
       Starting Application: OK  
    
    Проверяем, какие ресурсы доступны:
    
       vmc stats example101
       | Instance | CPU (Cores) | Memory (limit) | Disk (limit) | Uptime       |
       | 0        | 0.1% (4)    | 16.9M (512M)   | 40.0K (2G)   | 0d:0h:1m:22s |
    
    
    Увеличение числа одновременно выполняемых окружений для приложения example104 до 4:
    
       vmc instances example104 4
    
       Scaling Application instances up to 4: OK
    
    Проверяем, какие ресурсы доступны:
    
       vmc stats example104
    
       | Instance | CPU (Cores) | Memory (limit) | Disk (limit) | Uptime        |
       | 0        | 0.0% (4)    | 21.0M (128M)   | 28.0M (2G)   | 0d:0h:19m:33s |
       | 1        | 0.0% (4)    | 15.8M (128M)   | 27.9M (2G)   | 0d:0h:2m:38s  |
       | 2        | 0.0% (4)    | 16.3M (128M)   | 27.9M (2G)   | 0d:0h:2m:36s  |
       | 3        | 0.0% (4)    | 15.8M (128M)   | 27.9M (2G)   | 0d:0h:2m:37s  |
    
     
    ----* Использование системы виртуализации KVM в OpenIndiana (доп. ссылка 1)   [комментарии]
     
    В бета-версии 151 сборки проекта OpenIndiana, в рамках которого независимым
    сообществом развивается построенное на кодовой базе Illumos ответвление от
    OpenSolaris, появилась поддержка системы виртуализации KVM. Поддержка KVM была ранее
    портирована компанией
    Joyent для своей ОС SmartOS и на днях перенесена в Illumos (за исключением
    поддержки  KVM branded zone, которая пока не добавлена).
    
    <p>Для использования KVM пользователям последней доступной сборки oi_148
    необходимо выполнить обновление до oi_151_beta:
    
       sudo pkg set-publisher -g http://pkg.openindiana.org/dev-il -G http://pkg.openindiana.org/dev openindiana.org
       sudo pkg image-update --be-name oi_151_beta
    
    После чего можно подключить репозиторий с пакетами для работы с KVM и
    установить требуемые инструменты:
    
      sudo pkg set-publisher -p http://pkg.openindiana.org/kvm-test
      sudo pkg install driver/i86pc/kvm system/qemu system/qemu/kvm
    
    Управление окружениями производится при помощи стандартных утилит из состава
    QEMU. Использование libvirt пока не поддерживается.
    
    Пример использования.
    
    Создаем образ гостевой системы:
    
       qemu-img create -f qcow2 virt.img 15G 
    
    Устанавливаем операционную систему в гостевое окружение:
    
       qemu-kvm -hda virt.img -cdrom install_cd.iso -boot d -m 512
    
    Запускаем гостевое окружение (вместо qemu-kvm можно использовать qemu-system-x86_64):
    
       qemu-kvm -hda virt.img -net nic -net user
    
     
    ----* Изменение размера виртуального диска KVM/QEMU/VirtualBox   [комментарии]
     
    При необходимости расширения размера виртуального диска в формате qcow2,
    используемом в системах виртуализации  KVM и QEMU, можно обойтись без
    клонирования и создания нового образа.
    
    Завершаем работу виртуальной машины, связанной с изменяемым дисковым образом.
    
    Увеличиваем размер образа. В случае использования KVM/QEMU:
    
       qemu-img resize vm.qcow2 +5GB
    
    В случае использования VirtualBox, потребуется дополнительный шаг с
    промежуточным преобразованием VDI в qcow2 или raw-формат:
    
       qemu-img convert -f vdi -O qcow2 vm.vdi vm.qcow2
       qemu-img resize vm.qcow2 +5G
       qemu-img convert -f qcow2 -O vdi vm.qcow2 vm.vdi
    
    Другой вариант с использованием штатной утилиты VBoxManage:
    
       VBoxManage internalcommands converttoraw vm.vdi vm.raw
       qemu-img resize vm.raw +5G
       VBoxManage convertfromraw --format VDI --variant Standard vm.raw  vm.vdi
    
    Также можно создать новый большой VDI-раздел и клонировать в него старое содержимое:
    
       VBoxManage clonehd --existing old.vdi new.vdi
    
    
    Для задействования появившегося свободного пространства, необходимо расширить
    размер связанной с дисковым образом файловой системы. Для расширения ФС проще
    всего воспользоваться приложением gparted.
    Скачиваем из сети Live-дистрибутив Parted Magic или SystemRescueCd.
    Загружаем Live-дистрибутив в новой виртуальной машине, не забыв присоединить к
    ней изменяемый дисковый образ.
    После загрузки запускаем gparted, выбираем виртуальный диск и видим в хвосте
    нераспределенную область. Кликаем правой кнопкой мыши на имеющейся ФС и
    выбираем "Resize/Move", следуя дальнейшим подсказкам в интерфейсе.
    
    После завершения расширения размера, загружаем изначальную виртуальную машину и
    запускаем утилиту fsck для проверки раздела, размер которого был изменен:
    
       sudo fsck /dev/sda1
    
     
    ----* Использование cloud-init для запуска cloud-редакции Ubuntu в локальном KVM-окружении (доп. ссылка 1) (доп. ссылка 2)   [комментарии]
     
    В состав адаптированных для установки в cloud-окружениях сборок Ubuntu 10.10
    (UEC) был интегрирован cloud-init, конфигурируемый процесс инициализации,
    позволяющий унифицировать процесс задания конфигурации во время загрузки,
    например, указать локаль, имя хоста, SSH-ключи и точки монтирования.
    
    Ниже представлен скрипт по установке и преднастройке UEC-сборки в виде гостевой
    системы, работающей под управлением локального гипервизора KVM.
    
    # Загружаем свежую сборку UEC с http://uec-images.ubuntu.com,
    # например, стабильный выпуск Ubuntu 10.10 (http://uec-images.ubuntu.com/maverick/current/) 
    # или тестовую версию Ubuntu 11.04 (http://uec-images.ubuntu.com/natty/current/).
    
       uecnattyservercurrent=http://uec-images.ubuntu.com/server/natty/current/natty-server-uec-i386.tar.gz
    
    # Распаковываем img-образ и устанавливаем несколько переменных, указываем 
    # на ядро и базовые директории:
    
       tarball=$(basename $uecnattyservercurrent)
       [ -f ${tarball} ] || wget ${uecnattyservercurrent}
       contents=${tarball}.contents
       tar -Sxvzf ${tarball} | tee "${contents}"
       cat natty-server-uec-i386.tar.gz.contents
       base=$(sed -n 's/.img$//p' "${contents}")
       kernel=$(echo ${base}-vmlinuz-*)
       floppy=${base}-floppy
       img=${base}.img
    
    # Преобразуем образ UEC в формат qcow2, для запуска под управлением KVM:
    
       qemu-img create -f qcow2 -b ${img} disk.img
    
    # Подготавливаем набор мета-данных (файлы meta-data и user-data) для 
    # автоматизации настройки гостевой системы, примеры можно посмотреть здесь
    
    # Запускаем простейший HTTP-сервер для отдачи файлов с мета-данными 
    # Сервер будет запущен на 8000 порту и будет отдавать файлы meta-data 
    # и user-data из текущей директории, которые следует модифицировать в зависимости 
    # от текущих предпочтений (можно прописать команды по установке дополнительных пакетов, 
    # запустить любые команды, подключить точки монтирования и т.п.)
    
       python -m SimpleHTTPServer &
       websrvpid=$!
    
    # Запускаем гостевую систему под управлением KVM, базовый URL для загрузки 
    # мета-данных передаем через опцию "s=":
    
       kvm -drive file=disk.img,if=virtio,boot=on -kernel "${kernel}" \
          -append "ro init=/usr/lib/cloud-init/uncloud-init root=/dev/vda ds=nocloud-net;s=http://192.168.122.1:8000/ ubuntu-pass=ubuntu"
    
    # Завершаем выполнение http-сервера, используемого для отдачи мета-данных.
       kill $websrvpid
    
    
    
    Пример файла user-data:
    
       #cloud-config
       #apt_update: false
       #apt_upgrade: true
       #packages: [ bzr, pastebinit, ubuntu-dev-tools, ccache, bzr-builddeb, vim-nox, git-core, lftp ]
    
       apt_sources:
        - source: ppa:smoser/ppa
    
       disable_root: True
    
       mounts:
        - [ ephemeral0, None ]
        - [ swap, None ]
    
       ssh_import_id: [smoser ]
    
       sm_misc:
        - &user_setup |
          set -x; exec > ~/user_setup.log 2>&1
          echo "starting at $(date -R)"
          echo "set -o vi" >> ~/.bashrc
          cat >> ~/.profile <<EOF
          export EDITOR=vi
          EOF
    
       runcmd:
        - [ sudo, -Hu, ubuntu, sh, -c, 'grep "cloud-init.*running"  /var/log/cloud-init.log > ~/runcmd.log' ]
        - [ sudo, -Hu, ubuntu, sh, -c, 'read up sleep < /proc/uptime; echo $(date): runcmd up at $up | tee -a ~/runcmd.log' ]
        - [ sudo, -Hu, ubuntu, sh, -c, *user_setup ]
    
    Пример файла meta-data
    
       #ami-id: ami-fd4aa494
       #ami-launch-index: '0'
       #ami-manifest-path: ubuntu-images-us/ubuntu-lucid-10.04-amd64-server-20100427.1.manifest.xml
       #block-device-mapping: {ami: sda1, ephemeral0: sdb, ephemeral1: sdc, root: /dev/sda1}
       hostname: smoser-sys
       #instance-action: none
       instance-id: i-87018aed
       instance-type: m1.large
       #kernel-id: aki-c8b258a1
       local-hostname: smoser-sys.mosers.us
       #local-ipv4: 10.223.26.178
       #placement: {availability-zone: us-east-1d}
       #public-hostname: ec2-184-72-174-120.compute-1.amazonaws.com
       #public-ipv4: 184.72.174.120
       #public-keys:
       #  ec2-keypair.us-east-1: [ssh-rsa AAAA.....
       #      ec2-keypair.us-east-1, '']
       #reservation-id: r-e2225889
       #security-groups: default
    
     
    ----* Подготовка DomU FreeBSD-окружения для выполнения в Linux Dom0 Xen с LVM (доп. ссылка 1)   [комментарии]
     
    В качестве хост-системы будет использован сервер на базе Debian GNU/Linux 5, на
    котором дисковые разделы разбиты с использованием LVM.
    
    Для сборки работающего в режиме паравиртуализации ядра FreeBSD и формирования
    образа системы понадобится уже установленная FreeBSD. В простейшем случае можно
    воспользоваться VirtualBox для временной установки FreeBSD.
    
    Заходим в существующую FreeBSD систему и подготавливаем дисковый образ /tmp/freebsd.img для Xen.
    
       cd /usr/src
       truncate -s 1G /tmp/freebsd.img
    
    Привязываем файл с дисковым образом к устройству /dev/md0
    
       mdconfig -f freebsd.img
    
    Разбиваем разделы, форматируем и монтируем в /mnt:
    
       fdisk -BI /dev/md0
       bsdlabel -wB md0s1
       newfs -U md0s1a
       mount /dev/md0s1a /mnt
    
    Собираем мир и ядро с паравиртуальными драйверами Xen и устанавливаем в директорию /mnt:
    
       make buildworld
       make buildkernel KERNCONF=XEN 
       make DESTDIR=/mnt installworld
       make DESTDIR=/mnt installkernel KERNCONF=XEN 
       make DESTDIR=/mnt distribution
    
    В /mnt/etc/ttys добавляем строку с описанием терминала xc0
    
       xc0 "/usr/libexec/getty Pc" vt100 on secure
    
    В /mnt/etc/fstab прописываем параметры монтирования корня:
    
       /dev/ad0s1a / ufs rw 0 0
    
    Отмонтируем сформированный образ и скопируем его на хост-систему, на которой будет работать DomU:
    
       umount /mnt
       mdconfig -d -u 0
       bzip2 -v9 /tmp/freebsd.img
       scp /tmp/freebsd.img.bz2 user@dom0-host.example.com:/tmp/freebsd.img.bz2
    
    Отдельно копируем ядро с паравиртуальными драйверами:
    
       scp /usr/obj/usr/srcsys/XEN/kernel user@dom0-host.example.com:/tmp/freebsd_8.2-RC1_kernel
    
    
    Настраиваем Dom0
    
    Подготавливаем LVM-разделы, которые будут использоваться для работы FreeBSD.
    Создадим два раздела - один для изменения размера рабочего раздела и второй -
    рабочий раздел, на котором будет работать гостевая система.
    
    Создаем LVM-разделы в уже присутствующей физической группе xen-vol:
    
       lvcreate -L1000 -n freebsdmaint.example.com xen-vol
       lvcreate -L110000 -n freebsd-dom0.example.com xen-vol
    
    копируем ранее созданный образ в данные разделы:
    
       dd if=freebsd.img of=/dev/xen-vol/freebsdmaint.example.com bs=1M
       dd if=freebsd.img of=/dev/xen-vol/freebsd-dom0.example.com bs=1M
    
    Конфигурируем Xen:
    
    Создаем два файла конфигурации: первый для обслуживания изменения размера
    раздела и второй для рабочего виртуального окружения (отдельный раздел нужен
    так как мы не можем переконфигурировать текущий раздел без его отмонтирования,
    смонтировать файл через "mount -o loop" мы не можем так как в Linux отсутствует
    полноценная поддержка UFS).
    
    Ранее подготовленное ядро копируем в /xen/kernels/freebsd_8.2-RC1_kernel
    
    Окружение для изменения размера дискового раздела freebsdmaint.example.conf.cfg:
    
       kernel = "/xen/kernels/freebsd_8.2-RC1_kernel"
       vcpus = '1' # 1 CPU
       memory = '64' # 64 Мб ОЗУ
       disk = [ 'phy:/dev/xen-vol/freebsdmaint.example.com,hda,w',  'phy:/dev/xen-vol/freebsd-dom0.example.com,hdb,w' ]
       name = 'freebsdmaint.example.com'
       vif = [ 'bridge=eth0,mac=00:16:3E:62:DB:03' ]
       extra = 'xencons=tty1'
       extra = "boot_verbose"
       extra += ",boot_single"
       extra += ",kern.hz=100"
       extra += ",vfs.root.mountfrom=ufs:/dev/ad0s1a"
    
    Рабочее окружение freebsd-dom0.example.conf.cfg (отличается от предыдущей
    конфигурации указанием только одного раздела freebsd-dom0.example.com):
    
       kernel = "/xen/kernels/freebsd_8.2-RC1_kernel"
       vcpus = '1'
       memory = '64'
       disk = [ 'phy:/dev/xen-vol/freebsd-dom0.example.com,hda,w' ]
       name = 'freebsd-dom0.example.com'
       vif = [ 'bridge=eth0,mac=00:16:3E:62:DB:03' ]
       extra = 'xencons=tty1'
       extra = "boot_verbose"
       extra += ",boot_single"
       extra += ",kern.hz=100"
       extra += ",vfs.root.mountfrom=ufs:/dev/ad0s1a"
    
    Запускаем обслуживающее окружение:
    
       xm create -c freebsdmaint.example.conf.cfg
    
    Изменяем размер рабочего раздела, который виден как /dev/ad1s1a (после запуска
    fdisk на первые два вопроса отвечаем 'y', после запроса размера указываем
    размер основного раздела как "число Мб * 2048"):
    
       fdisk -u /dev/ad1
       
       ******* Working on device /dev/ad1 *******
       parameters extracted from in-core disklabel are:
       cylinders=14023 heads=255 sectors/track=63 (16065 blks/cyl)
    
       Figures below won't work with BIOS for partitions not in cyl 1
       parameters to be used for BIOS calculations are:
       cylinders=14023 heads=255 sectors/track=63 (16065 blks/cyl)
    
       Do you want to change our idea of what BIOS thinks ? [n] n
       Media sector size is 512
       Warning: BIOS sector numbering starts with sector 1
       Information from DOS bootblock is:
       The data for partition 1 is:
       sysid 165 (0xa5),(FreeBSD/NetBSD/386BSD)
       start 63, size 2088387 (1019 Meg), flag 80 (active)
       beg: cyl 0/ head 1/ sector 1;
       end: cyl 129/ head 254/ sector 63
       Do you want to change it? [n] y
       ...
       Supply a decimal value for "size" [2088387]
    
       fdisk: WARNING: partition does not end on a cylinder boundary
       fdisk: WARNING: this may confuse the BIOS or some operating systems
       Correct this automatically? [n] y
    
       Should we write new partition table? [n] y
    
    Изменяем размер слайса:
    
       bsdlabel -e /dev/ad1s1
    
       # size offset fstype [fsize bsize bps/cpg]
       a: 2088351 16 unused 0 0
       c: 2088387 0 unused 0 0 # "raw" part, don't edit
    
    Не трогаем значение "raw" и правим размер слайса "a", приписав туда вычисленное
    на прошлом шаге значение дискового раздела минус 16 байт. Т.е. получаем после
    правки (raw-значение рассчитается автоматически):
    
       # size offset fstype [fsize bsize bps/cpg]
       a: 225279416 16 unused 0 0
       c: 225279432 0 unused 0 0 # "raw" part, don't edit
    
    Запускаем growfs для расширения существующей файловой системы:
    
       growfs /dev/ad1s1a
    
    Выключаем обслуживающую VM и запускаем основную. Внимание, одновременно
    основной и обслуживающий VM запускать нельзя, так как они работают с одинаковым
    дисковым разделом freebsd-dom0.example.com.
    
     
    ----* Как подключить физический диск в VirtualBox   [комментарии]
     
    Иногда требуется использовать в VirtualBox не образ виртуального диска, а
    настоящее блочное устройство, такое как диск или USB Flash. В нашем случае,
    была поставлена задача загрузки в VirtualBox для проведения эксперимента копии
    одного из серверов, содержимое дисков которого было скопировано на
    USB-накопитель. При этом система должна была поддерживать загрузку не только в
    VirtualBox, но и без виртуализации - при соединении USB-накопителя к любому компьютеру.
    
    Для подключения блочного устройства /dev/sdc необходимо выполнить (тем же
    методом можно подключать отдельные разделы, например, /dev/sdc2):
    
       sudo VBoxManage internalcommands createrawvmdk -filename ~/.VirtualBox/HardDisks/sdc.vmdk -rawdisk /dev/sdc
    
    В дальнейшем, в настройках виртуальной машины выбираем образ sdc.vmdk, который
    ссылается на /dev/sdc. При подключении необходимо обратить внимание на права
    доступа к заданному блочному устройству, например, в нашем случае текущий
    пользователь должен входить в группу, для которой разрешена запись /dev/sdc.
    
     
    ----* Установка и запуск гостевой ОС на FreeBSD под VirtualBox без X11   Автор: Михаил Григорьев  [комментарии]
     
    Исходные данные: Сервер FreeBSD 8.1-RELEASE
    
    Задача: Запустить на VirtualBox гостевую ОС Windows или Ubuntu.
    
    Решение:
    
    1. Устанавливаем VirtualBox из портов (не забываем вначале обновить порты)
    
      cd /usr/ports/emulators/virtualbox-ose
    
      make config
    
       /------------------------------------------------------\
       |           Options for virtualbox-ose 3.2.10          |
       |                                                      |
       |  [ ] QT4             Build with QT4 Frontend         |
       |  [ ] DEBUG           Build with debugging symbols    |
       |  [X] GUESTADDITIONS  Build with Guest Additions      |
       |  [X] DBUS            Build with D-Bus and HAL support|
       |  [ ] PULSEAUDIO      Build with PulseAudio           |
       |  [ ] X11             Build with X11 support          |
       |  [ ] VDE             Build with VDE support          |
       |  [X] VNC             Build with VNC support          |
       |  [ ] WEBSERVICE      Build Webservice                |
       |  [ ] NLS             Native language support         |
       \------------------------------------------------------/
    
      make install
    
    2. Добавляем запуск модулей при старте сервера:
    
      echo vboxdrv_load="YES" >> /boot/loader.conf
    
    Загружаем нужный модуль:
    
      kldload vboxdrv
    
    3. Создаем пользователя vbox под которым будем запускать VirtualBox
    
      pw useradd vbox -c 'VirtualBox Daemon' -d /home/vbox -g vboxusers -w none -s /bin/sh
    
    4. Создаем домашний каталог пользователя vbox где будем хранить виртуалки
    
      mkdir /home/vbox
    
    5. Даем права:
    
      chown -R vbox:vboxusers /home/vbox/
      chmod -R 770 /home/vbox/
    
    6. Входим под пользователем и создаем виртуальную машину:
    
      Под рукой был только диск с Ubuntu, для Windows нужно лишь
      изменить опцию --ostype, имя виртуалки, имя hdd и путь до iso-образа.
      Список возможных значений --ostype смотрим командой: VBoxManage list ostypes
    
      su -l vbox
      VBoxManage createvm --name Ubuntu --ostype Ubuntu --register --basefolder /home/vbox
      VBoxManage modifyvm "Ubuntu" --memory 256 --acpi on --boot1 dvd --nic1 nat
      VBoxManage createhd --filename "Ubuntu.vdi" --size 10000 --remember
      VBoxManage storagectl "Ubuntu" --name "IDE Controller" --add ide --controller PIIX4
      VBoxManage storageattach "Ubuntu" --storagectl "IDE Controller" --port 0 --device 0 --type hdd --medium "Ubuntu.vdi"
      VBoxManage openmedium dvd /mnt/ubuntu-9.10-dvd-i386.iso
      VBoxManage storageattach "Ubuntu" --storagectl "IDE Controller" --port 0 --device 1 --type dvddrive --medium /mnt/ubuntu-9.10-dvd-i386.iso
    
    7. Смотрим конфигурацию созданной машины:
    
      VBoxManage showvminfo Ubuntu
    
    8. Создаем скрипт /usr/local/etc/rc.d/vbox.sh для запуска VirtualBox:
    
      #!/bin/sh
    
      echo "Starting VirtualBox..."
      su -l vbox -c '/usr/bin/nohup /usr/local/bin/VBoxHeadless --startvm Ubuntu --vnc --vncport 2222 --vncpass 1234567890 &'
    
    9. Подключаемся к VirtualBox с помощью любого VNC клиента. (порт 2222, пароль 1234567890)
    
    10. Устанавливаем и настраиваем ОС, ставим на неё VirtualBox GuestAdditions.
    
    На этом все, если есть вопросы, пишите, буду рад ответить.
    (с) Михаил Григорьев (sleuthhound@gmail.com)
    
     
    ----* Преобразование дисковых разделов для VirtualBox и обратно   [комментарии]
     
    Преобразование существующего дискового раздела в формат виртуальной машины VirtualBox.
    
    Создаем слепок дискового раздела /dev/sda1
    
       dd if=/dev/sda1 bs=512k of=os_image.img
    
    Преобразуем созданный образ в формат VDI:
    
       VBoxManage convertdd os_image.img os_image.vdi --format VDI
    
    
    
    Преобразование образа виртуальной машины для записи на диск/Flash.
    
    Если внутри виртуального диска один раздел, конвертируем VDI в сырой дамп:
    
       VBoxManage internalcommands converttoraw os_image.vdi os_image.img
    
    или 
    
       VBoxManage clonehd os_image.vdi /путь/os_image.img --format RAW
    
    Вычисляем смещение до нужного раздела:
    
       fdisk os_image.img
    
       Команда (m для справки): p
    
       Диск os_image.img: 0 МБ, 0 байт
       16 heads, 63 sectors/track, 0 cylinders
       Units = цилиндры of 1008 * 512 = 516096 bytes
       Sector size (logical/physical): 512 bytes / 512 bytes
       I/O size (minimum/optimal): 512 bytes / 512 bytes
       Disk identifier: 0x00000000
    
       Устр-во Загр     Начало    Конец    Блоки    Id  Система
       os_image.img1    1         213      107320+  83  Linux
    
    Раздел начинается с первого трека, значит смещение будет 63 * 512 = 32256
    
    Монтируем:
    
       sudo mount -o loop,offset=32256 os_image.img /mnt
    
    
    Записываем на диск /dev/sda8 (skip=63 - пропускаем 63 блока по 512 байт (bs=512)):
    
       dd if=os_image.img bs=512 skip=63 of=/dev/sda8
    
    если в образе больше одного раздела необходимо также указать размер копируемых
    данных через опцию count=N, где N - размер в 512 байтных блоках.
    
    Локальное монтирование статического VDI-образа.
    К ранее рассчитанному смещению для дискового раздела, нужно учесть размер
    заголовка (512 байт) и системного индекса VDI (4 байт на каждый мегабайт
    размера VDI).
    
       ls -al os_image.vdi
       -rw------- 1 test test 110101504 2010-12-20 21:47 os_image.vdi
    
    Для диска размером 105 Мб получаем смещение: 32256 + 512 + 4*(110101504/(1024*1024)) = 33188
    
    Значение 33188 дополняем до границы в 512 байт:
       echo "33188 - 33188 % 512 + 512" | bc
       33280
    
    Монтируем:
    
       mount -o loop,offset=33280 os_image.vdi /mnt/vdi
    
    Внимание ! Монтирование динамически расширяемых VDI невозможно, так как они
    имеют неоднородную структуру.
    
    Изменение размера VDI-образа:
    
    Самый простой способ создать пустой VDI нужного размера, из виртуального
    окружения разметить на нем ФС и скопировать данные. Любители графических
    интерфейсов могут загрузить в виртуальном окружении LiveCD c gparted (http://gparted.sourceforge.net/).
    
    Дополнение от pavlinux:
    
    Еще один метод локального монтирования статического VDI-образа.
    
       # modprobe nbd max_part=8 nbds_max=1
       # qemu-nbd --connect=/dev/nbd0 WindowsXPSP3.vdi
       # fdisk -l /dev/nbd0
    
       Устр-во Загр     Начало       Конец       Блоки   Id  Система
       /dev/nbd0p1   *           1        2813    22595391    7  HPFS/NTFS
    
       # mount -t ntfs-3g /dev/nbd0p1 /media/foofeel
       # ls  /media/foofeel
    
       AUTOEXEC.BAT  boot.ini    Documents and Settings  MSDOS.SYS 
    
     
    ----* VirtualBox на отдельной виртуальной консоли (доп. ссылка 1)   Автор: Wizard  [комментарии]
     
    При локальном использовании VitrualBox'а можно запускать виртуальные машины на
    отдельных виртуальных консолях с переключением по Ctrl+Alt+Fn с помощью xinit(1).
    
    Пример для 8-й консоли (Гость - Ctrl+Alt+F8, хост - Ctrl+Alt+F7):
    
       xinit /usr/bin/VirtualBox --startvm "My beloved VM" --fullscreen -- /usr/bin/Xorg :1
    
    Соответственно, при желании запуска таким образом более одной виртуальной
    машины, необходимо увеличивать номер виртуального терминала для X-сервера (:2,
    :3 и т.д.) и, конечно, указывать соответствующие имена виртуальных машин в
    параметре "--startvm".
    
     
    ----* Использование контейнеров LXC в Debian/Ubuntu   Автор: Heretic  [комментарии]
     
    Контейнеры LXC позволяют изолировать процессы и ресурсы, работающие в рамках
    одной операционной системы, не прибегая к использованию виртуализации.
    Положительным аспектом LXC является использование единого пространства
    системных буферов, например, единый для базовой системы и всех контейнеров
    дисковый кэш. Наиболее близкими аналогами LXC являются Solaris Zones и FreeBSD jail.
    
    В качестве серверной операционной системы была использована Ubuntu 10.04 LTS, в
    качестве виртуальных машин использован Debian Lenny.
    
    Организация сетевого соединения для контейнера.
    
    Воспользуемся сетевым мостом для создания общего сегмента сети.
    Устанавливаем пакеты для создания моста:
    
       sudo aptitude install bridge-utils
    
    Настроим мост, для этого приведем файл /etc/network/interfaces к следующему виду:
    
       # The loopback network interface
       auto lo
       iface lo inet loopback
    
       # Комментируем активные до настройки сетевого моста опции
       #allow-hotplug eth0
       #iface eth0 inet dhcp
    
       # Setup bridge
       auto br0
       iface br0 inet dhcp
        bridge_ports eth0
        bridge_fd 0
    
    Как можно увидеть из файла /etc/network/interfaces, eth0 закомментирован и
    добавлен новый интерфейс br0.
    
    Далее перезапускаем сеть:
    
        sudo /etc/init.d/networking restart
    
    Если использует ручная настройка сети, то нужно сделать так:
    
       auto br0
       iface br0 inet static
        bridge_ports eth0
        bridge_fd 0
        address 192.168.82.25
        netmask 255.255.255.0
        gateway 192.168.82.1
        dns-nameservers 192.168.82.1
    
    Установка LXC, установка cgroups
    
    Установим lxc: 
    
       sudo aptitude install lxc
    
    Создадим директорию /cgroup и примонтируем cgroup (может быть где угодно):
    
       sudo mkdir /cgroup
    
    Добавляем следующие строки в /etc/fstab:
    
       cgroup        /cgroup        cgroup        defaults    0    0
    
    И монтируем cgroups:
    
       sudo mount cgroup
    
    До того как начать собирать контейнер, проверим окружение через lxc-checkconfig:
    
    
       lxc-checkconfig
    
       Kernel config /proc/config.gz not found, looking in other places...
       Found kernel config file /boot/config-2.6.32-3-686
       --- Namespaces ---
       Namespaces: enabled
       Utsname namespace: enabled
       ...
    
    Все параметры должны быть включены (для ubuntu 10.04, в Debian squeeze Cgroup
    memory controller: disabled ).
    
    Создание первого контейнера
    
    Мы будем использовать оригинальную версию скрипта lxc-debian, он находится в
    файле /usr/share/doc/lxc/examples/lxc-debian.gz.
    
    Скопируем файл /usr/share/doc/lxc/examples/lxc-debian.gz в /usr/local/sbin/
    распакуем его и поставим бит запуска:
    
       sudo cp /usr/share/doc/lxc/examples/lxc-debian.gz /usr/local/sbin/
       sudo gunzip /usr/local/sbin/lxc-debian.gz
       sudo chmod +x /usr/local/sbin/lxc-debian
    
    Перед запуском этого скрипта требуется установить debootstrap.
    
       sudo aptitude install debootstrap
    
    Теперь сделаем первую вирутальную машину. По умолчанию директория развертывания
    контейнеров находится в /var/lib/lxc/ , параметром -p можно указать
    произвольное расположение вируальной машины.
    
       sudo mkdir -p /lxc/vm0
       sudo lxc-debian -p /lxc/vm0
    
    Это может занять некоторое время. Скрипт так же настроит локаль. После
    окончания установки нужно настроить виртуальную машину.
    Идем в /lxc/vm0 и правим файл конфигурации (config):
    
       lxc.tty = 4
       lxc.pts = 1024
       lxc.rootfs = /srv/lxc/vm0/rootfs
       lxc.cgroup.devices.deny = a
       # /dev/null and zero
       lxc.cgroup.devices.allow = c 1:3 rwm
       lxc.cgroup.devices.allow = c 1:5 rwm
       # consoles
       lxc.cgroup.devices.allow = c 5:1 rwm
       lxc.cgroup.devices.allow = c 5:0 rwm
       lxc.cgroup.devices.allow = c 4:0 rwm
       lxc.cgroup.devices.allow = c 4:1 rwm
       # /dev/{,u}random
       lxc.cgroup.devices.allow = c 1:9 rwm
       lxc.cgroup.devices.allow = c 1:8 rwm
       lxc.cgroup.devices.allow = c 136:* rwm
       lxc.cgroup.devices.allow = c 5:2 rwm
       # rtc
       lxc.cgroup.devices.allow = c 254:0 rwm
    
       # <<<< Добавляем эти строки
       lxc.utsname = vm0
       lxc.network.type = veth
       lxc.network.flags = up
       lxc.network.link = br0
       # lxc.network.name = eth0
       # lxc.network.hwaddr = 00:FF:12:34:56:78
       lxc.network.ipv4 = 192.168.82.28/24
    
    
    Рассмотрим параметры поподробнее:
    
    lxc.utsname = vm0 Имя хоста виртуальной машины
    
    lxc.network.type = veth Тип сети с которой работаем (man lxc.conf), используем
    veth если работаем с мостом.
    
    lxc.network.flags = up Сообщаем что нужно поднимать сетевой интерфейс при запуске системы.
    
    lxc.network.link = br0 Мост через который будет работать вируальный интерфейс.
    
    lxc.network.name = eth0 Имя сетевого интерфейса в контейнере. Если не 
    устанавливать будет eth0, по умолчанию.
    
    lxc.network.hwaddr = 00:FF:12:34:56:78 Мак адрес устройства которое используется.
    
    lxc.network.ipv4 = 192.168.82.28/24 Сетевой адрес который будет присвоен виртуальному интерфейсу.
    
    Так же требуется отредактировать /etc/network/interfaces в контейнере (/lxc/vm0/rootfs/etc/network/interfaces)
    
    Создаем контейнер который связывает имя конрейнера с файлом настроек. Имя будет
    использовано для управления единичным контейнером.
    
       sudo lxc-create -n vm0 -f /lxc/vm0/config
    
    Запустим вируальную машину.
    
       sudo lxc-start -n vm0 -d
    
    Проверяем запущена ли она:
    
       sudo lxc-info -n vm0
    
       'vm0' is RUNNING
    
    Теперь можно подключиться к консоли контейнера используя lxc-console:
    
       sudo lxc-console -n vm0
    
    Вводим имя пользователя root и получаем вход в систему (без пароля).
    Устанавливаем пароль пользователю root:
    
       sudo passwd
    
    Добавляем не привилегированного пользователя.
    
       sudo adduser admin
    
    Хорошо наш контейнер работает, теперь остановим его делается это следующим образом:
    
       sudo lxc-stop -n vm0
    
    И проверяем его статус через lxc-info
    
       sudo lxc-info -n vm0
       'vm0' is STOPPED
    
    
    Еще один контейнер
    
    У нас есть контейнер vm0 с минимальной системой и установленными паролями рута
    и не привилегированного пользователя, из этого контейнера клонируем еще один.
    Для этого первая виртуальная машина должна быть остановлена. Создаем папку vm1
    в /lxc и копируем туда содержимое vm0
    
       cd /lxc
       sudo mkdir vm1
       sudo cp -Rv ./vm0/* ./vm1/
       cd ./vm1/
    
    Теперь нужно подправить файл конфигурации для vm1 (сеть, имя и т.д.)
    
    Ограничения
    
    
    При настройке Xen или KVM можно настроить количество памяти, количество
    виртуальных процессов, а так же настроить планировщик. Это же можно сделать с
    помощью cgroups в LXC. Прежде нужно запомнить что все настройки cgroup
    полностью динамические, т.е. вы можете их изменять в любое время, так что
    будьте осторожны.
    
    Все значения cgroup можно задать следующими способами:
    
       lxc-cgroup -n vm0 <cgroup-name> <value>
       echo <value> > /cgroup/vm0/<cgroup-name>
    
    в конфигурационном файле: "lxc.cgroup.<cgroup-name> = <value>"
    
    В примерах будем использовать настройку через конфигурационный файл.
    
    Для обозначения размера, например памяти, можно использовать K, M или G, например:
    
       echo "400M" > /cgroup/vm0/memory.limit_in_bytes
    
    Допустимые параметры. Для начала, мы можем посмотреть в каталог /cgroup/vm0
    (если vm0 не запущен - запустите сейчас). Мы можем увидеть следующее:
    
       ls -1 /cgroup/vm0/
    
       cgroup.procs
       cpuacct.stat
       cpuacct.usage
       cpuacct.usage_percpu
       cpuset.cpu_exclusive
       cpuset.cpus
       cpuset.mem_exclusive
       cpuset.mem_hardwall
       cpuset.memory_migrate
       cpuset.memory_pressure
       cpuset.memory_spread_page
       cpuset.memory_spread_slab
       cpuset.mems
       cpuset.sched_load_balance
       cpuset.sched_relax_domain_level
       cpu.shares
       devices.allow
       devices.deny
       devices.list
       freezer.state
       memory.failcnt
       memory.force_empty
       memory.limit_in_bytes
       memory.max_usage_in_bytes
       memory.memsw.failcnt
       memory.memsw.limit_in_bytes
       memory.memsw.max_usage_in_bytes
       memory.memsw.usage_in_bytes
       memory.soft_limit_in_bytes
       memory.stat
       memory.swappiness
       memory.usage_in_bytes
       memory.use_hierarchy
       net_cls.classid
       notify_on_release
       tasks
      
    Не будем вдаваться в описание каждого параметра, подробно можно посмотреть здесь.
    
    Ограничение памяти и файла подкачки
    
    Не снижайте количество памяти для запущенного контейнера, если вы не уверены что делаете.
    Максимальное количество памяти для виртуальной машины:
    
       lxc.cgroup.memory.limit_in_bytes = 256M
    
    Максимальное количество swap для виртуальной машины:
    
       lxc.cgroup.memory.memsw.limit_in_bytes = 1G
    
    Больше информации по работе с памятью можно найти  здесь.
    
    Ограничение CPU
    
    Есть два варианта ограничения CPU. Первый, можно ограничить через планировщик и
    второй - можно ограничить через cgroup.
    
    Планировщик 
    Планировщик работает следующим образом: Можно присвоить vm0 значение 10 и vm1
    значение 20. Это означает что каждую секунду процессорного времени vm1 получит
    двойное количество циклов процессора. По умолчанию значение установлено в 1024.
    
       lxc.cgroup.cpu.shares = 512
    
    Больше о планировщике CPU читаем здесь.
    
    Так же можно установить количество используемых процессоров в контейнере.
    Допустим у вас 4 CPU, то по умолчанию для всех является значение 0-3
    (использовать все процессоры).
    
    Использовать первый cpu:
    
       lxc.cgroup.cpuset.cpus = 0
    
    использовать первый, второй и последний cpu.
    
       lxc.cgroup.cpuset.cpus = 0-1,3
    
    использовать первый и последний cpu.
    
       lxc.cgroup.cpuset.cpus = 0,3
    
    Подробнее здесь.
    
    Ограничение жесткого диска
    
    Пока это нельзя сделать через cgroups, но можно сделать через LVM.
    
    
    Как безопасно остановить виртуальную машину
    
    lxc-stop просто убивает родительский процесс lxc-start, если  требуется
    безопасно выключить, то в настоящие время не существует другого решения, как
    остановить виртуальную машину через SSH или lxc-console:
    
       sudo lxc-console -n vm0
       #vm0> init 0
    
    Нужно подождать пока остановятся все процессы (за этим можно понаблюдать через
    pstree или htop) и затем останавливаем виртуальную машину.
    
       sudo lxc-stop -n vm0
    
    Как навсегда удалить виртуальную машину
    
    Останавливаем виртуальную машину и используем команду lxc-destroy
    
       sudo lxc-destroy -n vm0
    
    Она удалит все файлы из /lxc/vm0, так сказано в документации, но она не удалила
    файлы из каталога поэтому пришлось удалять самому.
    
    Как заморозить и "разморозить" контейнер
    
    LXC может заморозить все процессы в запущенном контейнере, тем самым LXC просто
    блокирует все процессы.
    
       sudo lxc-freeze -n vm0
    
    После запуска все будет записано в память (и swap).
    
    Использованные источники
    * http://www.ibm.com/developerworks/ru/library/l-lxc-containers/
    * https://help.ubuntu.com/community/LXC
    * http://blog.bodhizazen.net/linux/lxc-configure-ubuntu-lucid-containers/
    * http://blog.bodhizazen.net/linux/lxc-linux-containers/
    * http://lxc.teegra.net/#_setup_of_the_controlling_host
    * http://blog.foaa.de/2010/05/lxc-on-debian-squeeze/#pni-top0
    
     
    ----* Запуск виртуальных машин Qemu и KVM в распределенном хранилище Sheepdog (доп. ссылка 1)   [комментарии]
     
    Пример настройки Sheepdog в Fedora Linux для организации выполнения в Qemu или
    KVM  виртуального окружения поверх распределенного на несколько машин
    высоконадежного хранилища Sheepdog (подробнее см. http://www.opennet.dev/27251/ )
    
    
    Устанавливаем и запускаем кластерный движок Corosync (http://www.corosync.org/)
    на всех узлах кластера хранения:
    
       yum install corosync
       service corosync start
    
    После интеграции sheepdog-драйвера в состав пакета qemu и qemu-kvm, достаточно будет выполнить:
    
       yum install qemu-kvm
    
    (сейчас еще нужно собирать драйвер из исходных текстов)
    
    
    Запускаем на каждом узле кластера хранения управляющий процесс Sheepdog,
    передав в качестве аргумента директориею для хранения объектов в локальной ФС каждого узла:
    
       sheep /store
    
    Форматируем и настраиваем параметры кластера хранения, указываем дублирование
    каждого блока данных на три разных узла:
    
       collie cluster format --copies=3
    
    Создаем в распределенном хранилище дисковый образ, размером 256Гб, для
    виртуальной машины с именем Alice:
    
       qemu-img create sheepdog:Alice 256G
    
    Импортируем существующий образ виртуальной машины в распределенное хранилище с именем Bob:
    
       qemu-img convert ~/amd64.raw sheepdog:Bob
    
    Смотрим список активных хранилищ:
    
       collie vdi list
    
       Bob          0  2.0 GB  1.6 GB  0.0 MB 2010-03-23 16:16      80000
       Alice        0  256 GB  0.0 MB  0.0 MB 2010-03-23 16:16      40000
    
    Запускаем виртуальную машину:
    
       qemu-system-x86_64 sheepdog:Alice
    
    Создаем снапшот виртуальной машины Alice:
    
       qemu-img snapshot -c name sheepdog:Alice
    
    Параллельно запускаем созданный снапшот:
    
       qemu-system-x86_64 sheepdog:Alice:1
    
    Клонируем снапшот Alice:1 в новую виртуальную машину Charlie
    
       qemu-img create -b sheepdog:Alice:1 sheepdog:Charlie
    
    Просматриваем состояние узлов кластера:
    
       collie node list
    
     
    ----* Запуск Firefox в контейнере OpenVZ (доп. ссылка 1)   [комментарии]
     
    Для повышении безопасности при просмотре в Firefox небезопасных сайтов, браузер
    можно дополнительно изолировать от системы, запустив его в контейнере OpenVZ.
    
    Создаем контейнер на базе шаблона Fedora 12:
    
       vzctl create 777 --ostemplate fedora-12-x86
       vzctl start 777
    
    Настраиваем внутри контейнера доступ к сети, используя NAT ( см. инструкцию
    http://wiki.openvz.org/NAT). Не забываем прописать ДНС-сервер в /etc/resolv.conf.
    
    Проверяем:
    
       vzctl exec 777 ping -c 1 openvz.org
    
    Устанавливаем в контейнер Firefox:
    
       vzctl exec 777 yum install firefox xauth liberation\*fonts
    
    Разрешаем перенаправление X11-соединений в ssh:
    
       vzctl exec 777 sed 's/^.*X11Forwarding .*$/X11Forwarding yes/'
       vzctl exec 777 /etc/init.d/sshd restart
    
    Создаем аккаунт пользователя для запуска Firefox:
    
       vzctl set 777 --userpasswd ffox:mysecpass
    
    Запускаем Firefox из контейнера:
    
       ssh -Y x.x.x.x dbus-launch firefox -no-remote
    
     
    ----* Подготовка паравиртуализированного гостевого окружения с FreeBSD 8 для Xen (доп. ссылка 1) (доп. ссылка 2) (доп. ссылка 3)   [комментарии]
     
    В заметке рассказано о подготовке образа гостевой системы с FreeBSD 8,
    предназначенного для работы под управлением  Xen в режиме паравиртуализации,
    позволяющем добиться более высокой производительности по сравнению с
    HVM-режимом (полная аппаратная виртуализация).
    
    В настоящее время нет готовых бинарных образов ядра и системы, предназначенных
    для установки в роли гостевой ОС. Придется создавать их вручную. Для начала
    поставим FreeBSD обычным образом на диск или под управлением VirtualBox, после
    чего займемся созданием образа, пригодного для использования в Xen DomU.
    
    Создадим каркас будущего образа гостевой ОС (размер можно сразу изменить исходя из решаемых задач):
    
       # truncate -s 256M freebsd.img
    
    Привяжем к этому файлу виртуальный диск:
    
       # mdconfig -f freebsd.img
    
    Установим загрузчик, создадим дисковые разделы и отформатируем под UFS2 с включенными softupdates:
    
       # fdisk -BI md0
       # bsdlabel -wB md0s1
       # newfs -U md0s1a
    
    Монтируем локально созданную внутри файла ФС:
    
       # mount /dev/md0s1a /mnt
    
    В /usr/src текущей системы должен быть полный набор исходных текстов, обновим их:
    
       # csup -h cvsup2.ru.FreeBSD.org -L 2 /usr/share/examples/cvsup/standard-supfile
    
    Примечание: C 2012 года проект FreeBSD перешёл на использование Subversion.
    Вместо cvsup следует использовать svnup (или freebsd-update для системы,
    portsnap/pkg для портов):
    
       cd /usr/ports/net/svnup && make install
       svnup stable -h svn0.us-west.freebsd.org 
       svnup ports -h svn0.us-west.freebsd.org 
    
    
    
    Соберем ядро и мир
    
       # make buildworld && make buildkernel KERNCONF=XEN
    
    Установим итоговые собранные файлы на ранее подготовленный дисковый образ в
    файле, примонтированный в /mnt:
    
       # export DESTDIR=/mnt && make installworld && make installkernel KERNCONF=XEN && cd etc && make distribution
    
    Адаптируем настройки для работы в качестве гостевой системы Xen.
    В  /mnt/etc/fstab добавим:
    
       /dev/xbd0       /               ufs     rw              1       1
    
    В /mnt/etc/ttys:
    
       xc0     "/usr/libexec/getty Pc"         vt100   on  secure
    
    Сохраним отдельно ядро гостевой системы, так как его потребуется скопировать для загрузки из dom0:
    
       # cp /mnt/boot/kernel/kernel /some/place/freebsd-kernel
    
    Отмонтируем виртуальный диск:
    
       # umount /mnt
       # mdconfig -d -u md0
    
    В результате получены файл с гостевой системой freebsd.img и файл с ядром freebsd-kernel.
    
    
    Конфигурируем управляющее окружение Xen (dom0):
    
    Проверяем работает ли xen:
    
       # xm list
    
    Создаем файл конфигурации /etc/xen/freebsd:
    
       kernel = "/virt/freebsd-8.0p2-i386-xen-domu-kernel"
       memory = 512
       name = "freebsd"
       vif = [ '' ]
       disk = [ 'file:/virt/freebsd-8.0p2-i386-xen-domu.img,hda,w' ]
       extra = "boot_verbose=1"
       extra += ",vfs.root.mountfrom=ufs:/dev/ad0s1a"
       extra += ",kern.hz=100"
    
    где, /virt/freebsd-8.0p2-i386-xen-domu-kernel путь к предварительно
    скопированному в файловую систему dom0 подготовленного ранее ядра FreeBSD.
    
    
    В /etc/xen/xend-config.sxp активируем сетевой мост для работы сети внутри FreeBSD:
    
       #(network-script network-dummy)
       (network-script network-bridge)
    
    Запускаем гостевое окружение и сразу входим в консоль:
    
       # xm create freebsd
       # xm console freebsd
    
    Из проблем, отмечена неработа настройки ifconfig_xn0="DHCP", для получения
    адреса dhclient нужно запускать вручную.
    
     
    ----* Настройка кластера для запуска Cloud-окружений с использованием Ubuntu Enterprise Cloud (доп. ссылка 1)   [комментарии]
     
    Для настройки сервера для запуска Cloud-окружений будем использовать
    дистрибутив Ubuntu Enterprise Cloud (http://www.ubuntu.com/cloud/private) в
    который интегрирована поддержка платформы Eucalyptus
    (http://www.eucalyptus.com/). Будет создан один управляющий
    cloud-инфраструктурой фронтэнд-сервер и несколько работающих под его началом
    вспомогательных узлов.
    
    Установленный на машинах процессор должен поддерживать средства аппаратной
    виртуализации Intel VTx (vmx) или AMD-V (svm). Проверить поддержку можно
    убедившись наличие соответствующих флагов в файле   /proc/cpuinfo:
    
       egrep '(vmx|svm)' /proc/cpuinfo
    
    Устанавливаем на сервер и вспомогательные узлы  Linux дистрибутив Ubuntu Server
    9.10, выбрав в меню загрузчика "Install Ubuntu Enterprise Cloud". Далее
    проводим инсталляцию с соответствие с личными предпочтениями, а в блоке "Cloud
    Installation Mode" выбираем  для управляющего сервера значение по умолчанию
    "Cluster", а при установке дополнительных узлов - "Node".
    
    Настройка вспомогательных узлов Cloud-инфраструктуры.
    
    Устанавливаем на узлах публичный SSH-ключ управляющего сервера:
    1. Задаем пользователю eucalyptus на конечных узлах пароль:
    
       sudo passwd eucalyptus
    
    2. На стороне управляющего сервера запускаем команду копирования ssh-ключа на узлы:
    
       sudo -u eucalyptus ssh-copy-id -i ~eucalyptus/.ssh/id_rsa.pub eucalyptus@IP_адрес_узла
    
    3. Очищаем ранее установленный пароль для пользователя eucalyptus, чтобы
    заходить можно было только по ключам шифрования:
    
       sudo passwd -d eucalyptus
    
    После того как аутентификация по ssh-ключам настроена на всех узлах запускаем
    на стороне управляющего сервера процесс регистрации узлов:
    
       sudo euca_conf --no-rsync --discover-nodes
    
    Получаем и устанавливаем мандат для пользователей cloud-инфраструктуры.
    
    На управляющем пользователе создаем директорию ~/.euca и генерируем
    идентификационные параметры cloud-инфраструктуры:
    
       mkdir -p ~/.euca
       chmod 700 ~/.euca
       cd ~/.euca
       sudo euca_conf --get-credentials mycreds.zip
       unzip mycreds.zip
       cd -
    
    Настройка EC2 API и AMI утилит.
    
    На управляющем сервере запускаем скрипт для создания параметров окружения Eucalyptus:
    
       ~/.euca/eucarc
    
    Для автоматизации запуска добавляем его вызов в ~/.bashrc:
    
       echo "[ -r ~/.euca/eucarc ] && . ~/.euca/eucarc" >> ~/.bashrc
    
    Устанавливаем вспомогательный набор AMI утилит:
    
       sudo apt-get install ec2-ami-tools ec2-api-tools
    
    Для проверки, что все работает, запускаем:
    
       . ~/.euca/eucarc
    в ответ должно появиться:
       euca-describe-availability-zones verbose
    
    Настройка через управляющий web-интерфейс
    
    В браузере открываем страницу https://IP_управляющего_сервера:8443
    В качестве имени пользователя и пароля указываем "admin". После первого входа
    будет сразу предложено поменять пароль и указать контактный email.
    
    Установка образов пользовательских cloud-окружений.
    
    В панели управления web-интерфейса выбираем вкладку "Store" и жмем кнопку
    "Install" рядом с выбранным в списке образом системы. Сразу после нажатия
    начнется загрузка из сети выбранного образа и затем его установка.
    
    Запуск образов пользовательских cloud-окружений.
    
    Перед первым стартом окружения на узле создаем для него SSH-ключ на управляющем узле:
    
       touch ~/.euca/mykey.priv
       chmod 0600 ~/.euca/mykey.priv
       euca-add-keypair mykey > ~/.euca/mykey.priv
    
    На узле открываем 22 порт, запустив следующие команды:
    
       euca-describe-groups
       euca-authorize default -P tcp -p 22 -s 0.0.0.0/0
    
    После этого можно запустить зарегистрированный образ окружения через
    web-интерфейс: во вкладке "Store" выбираем ссылку "How to Run", в появившемся
    окне будет отражена полная команда для запуска. Первый запуск может занять
    довольно долго, так как потребуется время на его копирование в кеш.
    
    За статусом запуска окружения можно наблюдать выполнив команду:
    
       watch -n5 euca-describe-instances
    
    Когда состояние "pending" заменится на "running", к окружению можно подключаться.
    
    Для сохранения IP созданного окружения в переменной IPADDR и входа в него по ssh выполним команду:
    
       IPADDR=$(euca-describe-instances | grep $EMI | grep running | tail -n1 | awk '{print $4}')
       ssh -i ~/.euca/mykey.priv ubuntu@$IPADDR
    
    Для принудительного завершения работы окружения:
    
       INSTANCEID=$(euca-describe-instances | grep $EMI | grep running | tail -n1 | awk '{print $2}')
       euca-terminate-instances $INSTANCEID
    
    
    Полезная информация
    
    Перезапуск управляющего сервера eucalyptus:
    
       sudo service eucalyptus restart
    
    Для перезапуска ПО на стороне узла:
    
       sudo service eucalyptus-nc restart
    
    Лог сохраняется в /var/log/eucalyptus
    Файлы конфигурации находятся в директории /etc/eucalyptus
    БД: /var/lib/eucalyptus/db
    Ключи шифрования: /var/lib/eucalyptus и  /var/lib/eucalyptus/.ssh
    
    Подробнее см. официальное руководство пользователя http://help.ubuntu.com/community/UEC
    
     
    ----* Доступ к файлам виртуальных машин VMware ESX из Fedora Linux (доп. ссылка 1)   Автор: Andrey Markelov  [обсудить]
     
    Richard W.M. Jones в своем блоге опубликовал интересный пост
    (http://rwmj.wordpress.com/2010/01/06/examine-vmware-esx-with-libguestfs/) о
    работе при помощи утилит libguestfs с образами VMware ESX4. Немного дополнив,
    напишу, в чем суть.
    
    Во-первых нам понадобятся пакеты fuse-sshfs и guestfish. Первый позволяет
    монтировать при помощи FUSE удаленную файловую систему по SSH FTP, а второй
    установит в систему интерактивную командную оболочку, из которой можно получать
    доступ к образам дисков виртуальных машин, в том числе и vmdk. Естественно, в
    системе должны присутствовать стандартные компоненты виртуализации Fedora, в
    частности, работающий демон libvirtd.
    
    Для начала проверяем, какие присутствуют на хосте ESX виртуальные машины:
    
       $ virsh -c esx://192.168.1.12?no_verify=1 list --all
       Enter username for 192.168.1.12 [root]:
       Enter root password for 192.168.1.12:
       ID Имя Статус
       ----------------------------------
       208 www выполнение
       224 mail выполнение
       - 2RHEL5_DS отключить
       - 2W2003_DC отключить
       - RHEL5_IPA отключить
       - RHEL5_Satellite53 отключить
       - RHEL5_Server1 отключить
       - RHEL5_Station отключить
       - RHEL5_Station2 отключить
       - RHEL5_Zimbra отключить
    
    Далее смонтируем через FUSE соответствующую директорию файловой системы vmfs:
    
       $ mkdir esx
       $ sshfs root@192.168.1.12:/vmfs/volumes esx
       root@192.168.1.12's password:
       $ cd esx/
       $ ls
       4ac343f6-500e2828-d805-0022640793d2 LocalStorage1
    
    Естественно, мы ничего нового по сравнению с тем, что нам покажет vCenter
    client, не увидели. Далее переходим в директорию с нужной нам виртуальной машиной:
    
       $ cd LocalStorage1/RHEL5_IPA/
       $ ls
       RHEL5_IPA-flat.vmdk RHEL5_IPA.vmdk RHEL5_IPA.vmx vmware.log
       RHEL5_IPA.nvram RHEL5_IPA.vmsd RHEL5_IPA.vmxf
    
    При помощи новой утилиты virt-list-filesystems (в версии libguestfs репозитория
    Fedora 12 пока ее нет, зато есть в Rawhide) смотрим какие разделы доступны
    внутри образа:
    
       $ virt-list-filesystems -al RHEL5_IPA-flat.vmdk
       /dev/sda1 ext3
       /dev/vol0/home ext3
       /dev/vol0/root ext3
       /dev/sda3 swap
    
    И, наконец, запускаем интерактивную командную оболочку:
    
       $ guestfish --ro -a RHEL5_IPA-flat.vmdk -m /dev/vol0/root
    
       Welcome to guestfish, the libguestfs filesystem interactive shell for
       editing virtual machine filesystems.
    
       Type: 'help' for help with commands
       'quit' to quit the shell
    
       > ll /
       total 192
       drwxr-xr-x. 22 root root 4096 Oct 24 07:47 .
       dr-xr-xr-x 29 root root 0 Jan 8 12:59 ..
       drwxr-xr-x. 2 root root 4096 Oct 7 15:07 bin
       drwxr-xr-x. 2 root root 4096 Oct 7 13:45 boot
       drwxr-xr-x. 4 root root 4096 Oct 7 13:45 dev
       drwxr-xr-x. 93 root root 12288 Oct 24 07:47 etc
       drwxr-xr-x. 2 root root 4096 Oct 7 13:45 home
       ....
    
    Ну, а дальше man guestfish и help для списка команд оболочки. Для виртуальных
    машин с включенным SELinux крайне желательно использовать ключ --selinux, иначе
    при попытке записи файлов вы можете создать при монтировании образа r/w файлы
    без меток SELinux.
    
     
    ----* Как установить FreeBSD 8.0 DomU в окружении Xen Dom0 (доп. ссылка 1)   Автор: Василий Лозовой  [комментарии]
     
    Во FreeBSD 8.0 была объявлена экспериментальная поддержка DomU для Xen, что
    позволяет установить FreeBSD в паравиртуальном режиме и использовать все
    возможности Xen с FreeBSD.
    
    В качестве хост-окружения будем использовать Xen 3 в Debian GNU/Linux.
    Не забудьте скомпилировать hvmloader для поддержки HMV режима (режим полной
    виртуализации нужен для установки FreeBSD) и включить в BIOS поддержку
    аппаратной акселерации виртуализации.
    
    На данном этапе имеем  гипервизор Xen hypervisor (Dom0) в Linux:
    
       # xm list
       
       Name                                        ID   Mem VCPUs        State   Time
       Domain-0                                     0  3692     8     r----- 1799656.1
    
    Подготавливаем виртуальную машину для запуска на ней FreeBSD, выделяем место на диске.
    
    Создаем конфигурационный файл Xen (/etc/xen/freebsd_vps):
    
    
       kernel = "/usr/lib/xen/boot/hvmloader"
       builder='hvm'
       memory = 1024
       name = "FreeBSD VPS"
       vif = [ '' ]
       disk = [ 'phy:/dev/mylvm0/lvol9,hda,w', 'file:/.1/8.0-RELEASE-i386-dvd1.iso,hdc:cdrom,r' ]
       boot="cda"
       vnc=1
       vncpasswd=''
    
    Запускаем виртуальную машину:
    
       # xm create freebsd_vps
    
    Подключаемся к запущенному окружению при помощи vncviewer. Видим процесс
    загрузки FreeBSD и запуск инсталлятра sysinstall. Устанавливаем FreeBSD по
    своему усмотрению, не забыв установить полные исходные тексты FreeBSD для
    последующей пересборки.
    
    После того как система установлена, пересобираем ядро FreeBSD включив поддержку
    Xen. Собранное ядро копируем во внешнее управляющее Dom0 окружение.
    
       # cd /boot/kernel/
       scp /boot/kernel/kernel user@dom0-host:/usr/lib/xen/boot/kernel
    
    На FreeBSD в /etc/ttys добавляем консоль xc0:
    
       xc0 "/usr/libexec/getty Pc" vt100 on secure
    
    В управляющем Dom0 прописываем в параметры гостевой системы (файл
    /etc/xen/freebsd_vps) вызов ядра FreeBSD, собранного с поддержкой
    паравиртуализации, также отключаем HVM и убираем ссылку на загрузочный iso:
    
       kernel = "/usr/lib/xen/boot/kernel"
       memory = 1024
       name = "FreeBSD VPS"
       vif = [ 'bridge=outeth0', 'bridge=mir111', 'bridge=mir113', 'bridge=mir114', 'bridge=mir115' ]
       disk = [ 'phy:/dev/mylvm0/lvol9,hda1,w' ]
       extra = "boot_verbose=1"
       extra += ",vfs.root.mountfrom=ufs:/dev/ad0s1a"
       extra += ",kern.hz=100"
       pae=1
    
    В вышеприведенном примере подсоединено 5 сетевых интерфейсов.
    
    Перезагружаем FreeBSD в DomU паравиртуальном (PVM) режиме:
    
       # xm destroy freebsd_vps
       # xm create -c freebsd_vps
       # xm list
    
       Name ID Mem VCPUs State Time(s)
       Domain-0 0 3692 8 r----- 1800450.2
       FreeBSD 117 1024 1 r----- 137712.0
    
     
    ----* Установка и запуск OpenVZ на Debian Lenny (доп. ссылка 1)   Автор: DennisK  [комментарии]
     
    Имеем сервер с установленным Debian Lenny. Задача: настроить на серверe несколько VPS-ов.
    
    1. Устанавливаем ядро с поддержкой OpenVZ
    
          aptitude install linux-image-openvz-amd64
    
    2. Для нормальной работы OpenVZ-контейнеров необходимо чтобы /etc/sysctl.conf
    содержал следующие строки:
    
          net.ipv4.conf.all.rp_filter=1
          net.ipv4.icmp_echo_ignore_broadcasts=1
          net.ipv4.conf.default.forwarding=1
          net.ipv4.conf.default.proxy_arp = 0
          net.ipv4.ip_forward=1
          kernel.sysrq = 1
          net.ipv4.conf.default.send_redirects = 1
          net.ipv4.conf.all.send_redirects = 0
          net.ipv4.conf.eth0.proxy_arp=1
    
    3. Перезагружаем сервер
    
    4. Проверяем, что сервер загрузился с новым ядром
          uname -r
    
    если система выдаст 2.6.26-2-openvz-amd64, то всё установилось корректно
    
    5. Ядро, которое было установлено по-умолчанию мне не нужно и я его удаляю
    (если хотите оставить предыдущее ядро - шаг пропускаем)
    
          apt-get remove --purge linux-image-2.6.26-2-amd64
    
    6. Для контейнеров OpenVZ у меня выделен отдельный раздел подмонтированный в
    /vz. По-умолчанию OpenVZ в Debian всё складывает в /var/lib/vz. Переношу всё с
    /var/lib/vz в /vz и создаю симлинк
    
          /etc/init.d/vz stop
          mv /var/lib/vz/* /vz/
          rmdir /var/lib/vz
          ln -s /vz /var/lib/vz
          /etc/init.d/vz start
    
    7. В контейнере у меня будет работать Debian Lenny х86. Загружаем шаблон контейнера с сайта OpenVZ
    
          cd /var/lib/vz/template/cache
          wget -c http://download.openvz.org/template/precreated/debian-5.0-x86.tar.gz
    
    8. Создаём контейнер (101 - это уникальный идентификатор контейнера)
    
          vzctl create 101 --ostemplate debian-5.0-x86 --config vps.basic
    
    9. Указываем чтобы контейнер запускался в вместе с OpenVZ
    
          vzctl set 101 --onboot yes --save
    
    10. Конфигурируем имя хоста, IP и dns-сервер для контейнера
    
          vzctl set 101 --hostname vps1.local --save
          vzctl set 101 --ipadd 10.1.1.101 --save
          vzctl set 101 --nameserver 10.1.1.2 --save
    
    11. Запускаем контейнер  и устанавливаем пароль для root-a
    
          vzctl start 101
          vzctl exec 101 passwd
    
    12. Переключаемся в контейнер
    
          vzctl enter 101
    
    Для выхода из контейнера необходимо дать команду exit. Зайти можно и по ssh.
    
    13. Устанавливаем необходимое ПО в контейнере.
    
    14. Успешно эксплуатируем.
    
    P.S. Несколько необходимых команд для работы с контейнерами:
    
    vzlist -a - список запущенных контейнеров и их состояние
    vzctl stop <UID> - остановить контейнер
    vzctl restart <UID> - перезагрузить контейнер
    vzctl destroy <UID> - удалить контейнер
    
    где <UID> - уникальный идентификатор OpenVZ-контейнера
    
     
    ----* Создание бекапа OpenVZ контейнера (доп. ссылка 1)   [обсудить]
     
    Для создания инкрементального бэкапа по сети можно использовать готовый скрипт ezvzdump,
    суть работы которого в создании копии через rsync, заморозке окружения с
    сохранением дампа состояния (vzctl chkpnt $VEID --suspend
    ), копированию сохраненного дампа и изменившихся с момента последнего rsync
    файлов, продолжению работы остановленного OpenVZ контейнера (vzctl chkpnt $VEID --resume).
    
    Для создания целостных дампов можно воспользоваться утилитой vzdump:
    
       vzdump 777
    
    После этого образ текущего состояния OpenVZ контейнера будет сохранен в /vz/dump/
    
    Утилита vzdump также поддерживает схему suspend/rsync/resume:
    
       vzdump --suspend 777
    
    А также можно сохранить дамп почти мгновенно методом suspend/LVM2 snapshot/resume:
    
       vzdump --dumpdir /space/backup --snapshot 777
    
    В итоге будет сформирован архив /space/backup/vzdump-777.tar, который можно восстановить командой:
    
       vzdump --restore /space/backup/vzdump-777.tar 600
    
     
    ----* Запуск win2k3 на freebsd под virtualbox без x11 (доп. ссылка 1)   Автор: shurik  [комментарии]
     
    Задача: запустить виртуальную машину с win2k3 на хосте с freebsd без установленого Х-сервера.
    
    Имеем: 
       FreeBSD 7.2-RELEASE-p3, 
       virtualbox-3.0.51.r22226 (WITHOUT_QT4=true WITHOUT_DEBUG=true WITH_GUESTADDITIONS=true 
         WITHOUT_DBUS=true WITHOUT_PULSEAUDIO=true WITH_NLS=true)
    
    Сразу хочу заметить, что поскольку протокол VRDP в virtualbox под freebsd пока не реализован, 
    то для первоначальной инсталяции виртуальной машины нам все же понадобится другой хост 
    с установленным окружением X11. Установка win2k3 в виртуальное окружение -
    задача весьма тривиальная,
    поэтому её описание я опущу...
    
    Итак, мы имеем установленную виртуальную систему, которую нам необходимо пренести на 
    другой хост и попытаться там запустить. Для этого экспортируем виртуальную машину на хосте, 
    где мы ее устанавливали:
    
       VBoxManage export WIN2003STD -o ~/WIN2003STD.ovf
    
    где WIN2003STD - имя виртуальной машины, 
    ~/WIN2003STD.ovf - файл, в котором будут храниться экспортируемые параметры виртуальной машины. 
    
    В итоге имеем 3 файла, которые нам необходимо перенести на удаленный хост:
    
       WIN2003STD.mf - файл, содержащий контрольные суммы двух последующих файлов
       WIN2003STD.ovf - файл параметров экспортируемой машины
       WIN2003STD.vmdk - упакованный файл-образ жесткого диска виртуальной машины.
    
    Повторюсь, что поскольку реализации протокола VRDP в virtualbox для freebsd нет, 
    то изначально перед экспортом виртуальной машины нам необходимо будет дать удаленный доступ 
    внутрь гостевого окружения с помощью RDP или VNC. В моем случае я сделал доступ через 
    удаленный рабочий стол win2k3.
    
    На удаленном хосте я создал для запуска виртуального окружения отдельного пользователя 
    vbox с группой vboxusers, которому запретил вход через ssh. Файлы WIN2003STD.mf, WIN2003STD.ovf 
    и WIN2003STD.vmdk я положил в его домашнюю директорию и сделал их владельцем пользователя vbox. 
    
    Далее от пользователя vbox делаем импорт виртуальной машины:
    
       VBoxManage import ~/WIN2003STD.ovf
    
    Далее нам необходимо пробросить внутрь виртуальной машины tcp-порт 3389 для
    доступа к удаленному рабочему столу win2k3:
    
       VBoxManage setextradata WIN2003STD "VBoxInternal/Devices/pcnet/0/LUN#0/Config/RDP/HostPort" 3389
       VBoxManage setextradata WIN2003STD "VBoxInternal/Devices/pcnet/0/LUN#0/Config/RDP/GuestPort" 3389
       VBoxManage setextradata WIN2003STD "VBoxInternal/Devices/pcnet/0/LUN#0/Config/RDP/Protocol" tcp
    
    Если в виртуальной машине при конфигурирации был выбран сетевой адаптер Intel,
    то следует заменить в выше указанных строках pcnet на e1000.
    
    Все, виртуальную машину можно запускать:
    
       VBoxManage startvm WIN2003STD --type headless
    
    "--type headless" позволяет запутить виртуальную машину в фоновом режиме.
    
    О том, что проброс tcp-порта выполнен свидетельствуют строки в логе вмртуальной машины и sockstat:
    
       $ grep -i nat ~/.VirtualBox/Machines/WIN2003STD/Logs/VBox.log
    
       00:00:00.535 Driver = "NAT" (cch=4)
       00:00:00.538 AIS - Alternate Instruction Set = 0 (1)
       00:00:00.942 NAT: ICMP/ping not available (could open ICMP socket, error VERR_ACCESS_DENIED)
       00:00:00.942 NAT: value of BindIP has been ignored
       00:00:35.141 NAT: set redirect TCP hp:3389 gp:3389
       00:01:05.062 NAT: old socket rcv size: 64KB
       00:01:05.062 NAT: old socket snd size: 64KB
    
      $ sockstat -4 -l | grep 3389
    
       vbox VBoxHeadle 982 32 tcp4 :3389 :*
    
    Следует заметить, что icmp во внешний мир из виртуальной машины работать не
    будет, это требует прав суперпользователя,
    о чем нам сказано в логе - "00:00:00.942 NAT: ICMP/ping not available (could
    open ICMP socket, error VERR_ACCESS_DENIED)",
    поэтому проверять работоспособность сети внутри виртуального хоста с помощью
    ping не стоит. Все, задачу можно считать выполненной.
    
    P.S. После выключения удаленной виртуальной машины через сеанс RDP, система выпадает в BSOD и 
    дальше возможен вход только в безопасном режиме, что в нашем случае уже не возможно. Беглый поиск 
    в google дает нам такое решение - необходимо предварительно в ветке реестра 
       HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\intelppm\Start 
    выставить значение 4.
    
    P.P.S. Для автоматического старта виртуальной машины при старте системы я в
    /usr/local/etc/rc.d/ создал скрипт вида:
    
       #!/bin/sh
    
       echo "Starting VirtualBox..."
       su vbox -c '/usr/local/bin/VBoxManage startvm WIN2003STD --type headless'
    
     
    ----* Настройка аутентификации для управления окружениями в libvirt (доп. ссылка 1)   [обсудить]
     
    Настройка SASL DIGEST-MD5 аутентификации в libvirt для управления удаленными
    виртуальными окружениями
    в недоверительной сети. Для шифрования передаваемого трафика можно использовать TLS.
    
    Добавляем пользователя virt в SASL базу:
    
       saslpasswd2 -a libvirt virt
       Password:
       Again (for verification):
    
    Через опцию "-a" передаем имя приложения для привязки пользователя к нему. 
    Утилита saslpasswd2 входит в состав пакета cyrus-admin.
    
    Для просмотра списка пользователей из SASL базы libvirt выполняем:
    
       sasldblistusers2 -f /etc/libvirt/passwd.db
    
    Включаем механизм digest-md5 в /etc/sasl2/libvirt.conf:
    
       # Default to a simple username+password mechanism
       mech_list: digest-md5
    
    В настойках /etc/libvirt/libvirtd.conf разрешаем только SASL аутентификацию, при использовании TCP 
    для соединения необходимо поменять схему через директиву аутентификации auth_tcp:
    
       auth_tcp = "sasl"
    
    Но более правильно, чтобы не передавать пароли и другую важную информацию
    открытым текстом, использовать в качестве транспорта TLS, через определение
    директивы auth_tls:
    
       auth_tls = "sasl"
    
    Далее для TLS нужно сгенерирвать серверные и клиентские сертификаты, о создании
    которых рассказано здесь http://libvirt.org/remote.html
    
    
    После активации SASL, для каждой операции libvirt будет запрошен логин и пароль.
    
       $ virsh
    
       virsh # migrate --live kvmnode2 qemu+tls://disarm/system
       Please enter your authentication name:virt
       Please enter your password:
    
     
    ----* Управление гостевым окружением с CentOS/Fedora через последовательный порт (доп. ссылка 1)   [комментарии]
     
    Настройка управления виртуальным окружением через консоль virsh
    (http://www.libvirt.org/), без использования vnc-клиента.
    
    Перенаправляем вывод Grub для виртуального окружения в последовательный порт.
    В /boot/grub/menu.lst добавляем:
    
       serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1
       terminal --timeout=10 serial
    
    Отключаем показ заставки  splash и перенаправляем вывод ядра в последовательный порт (в menu.lst):
    
       title CentOS (2.6.18-128.1.10.el5)
    	root (hd0,0)
    	kernel /boot/vmlinuz-2.6.18-128.1.10.el5 ro root=LABEL=/ console=ttyS0
    	initrd /boot/initrd-2.6.18-128.1.10.el5.img
    
    Настраиваем запуск getty процесса для логина через ttyS0. В /etc/inittab прописываем:
    
       S0:12345:respawn:/sbin/agetty ttyS0 115200
    
    Разрешаем вход суперпользователем через ttyS0:
    
       echo "ttyS0" >> /etc/securetty
    
    Подключаемся к гостевому окружению kvmnode1 через команду virsh:
    
       $ virsh
    
       virsh # console kvmnode1
       Connected to domain kvmnode1
       Escape character is ^]
    
       CentOS release 5.3 (Final)
       Kernel 2.6.18-128.1.10.el5 on an x86_64
    
       kvmnode1 login:
    
     
    ----* Быстрая настройка qemu/kvm окружений при помощи virt-manager (доп. ссылка 1)   [комментарии]
     
    Для упрощения и унификации работы с различными системами виртуализации можно использовать 
    удобный фронтэнд virt-manager (http://virt-manager.et.redhat.com/).
    
    В Ubuntu ставим необходимые пакеты:
    
       sudo apt-get install kvm qemu libvirt-bin bridge-utils ubuntu-virt-mgmt ubuntu-virt-server 
    
    Отдельно GUI интерфейс можно поставить из пакетов virt-manager и virt-viewer.
    Пакет для формирования гостевых окружений: python-vm-builder
    Пакет для создание гостевых VM с другими ОС внутри: python-virtinst
    
    Добавляем себя в группу администраторов виртуальных серверов:
    
       sudo usermod -aG libvirtd `id -un`
    
    Далее, управление виртуальными машинами производится командой virsh.
    
    
    Создаем файл конфигурации test.xml и определяем новую виртуальную машину test c Ubuntu внутри:
    
       sudo python-vm-builder kvm jaunty \
                      --domain test \
                      --dest описание \
                      --arch i386 \
                      --hostname имя_хоста \
                      --mem объем_памяти_в_мегабайтах \
                      --user имя_пользователя \
                      --pass пароль \
                      --ip 192.168.0.12 \
                      --mask 255.255.255.0 \
                      --net 192.168.0.0 \
                      --bcast 192.168.0.255 \
                      --gw 192.168.0.1 \
                      --dns 192.168.0.1 \
                      --components main,universe \
                      --addpkg vim openssh-server \
                      --libvirt qemu:///system ;
    
       virsh dumpxml test > ~/test.xml
       редактируем test.xml
       virsh define ~/test.xml
    
    При необходимости создания гостевой VM с другой операционной системой, можно
    использовать python-virtinst:
    
       sudo virt-install --connect qemu:///system -n test -r 512 -f test.qcow2 -s 12 \
          -c test_inst.iso --vnc --noautoconsole --os-type linux --os-variant ubuntuJaunty --accelerate --network=network:default
    
    Для контроля процесса установки, соединяемся GUI интрфейсом:
    
       virt-viewer -c qemu:///system test  # локально
       virt-viewer -c qemu+ssh://ip_адрес_хоста/system test # с внешнего IP
    
    Если необходимо, чтобы гостевая ОС работала в отдельном разделе диска, то
    файловый образ нужно сконвертировать:
    
       sudo qemu-img convert root.qcow2 -O raw /dev/sdb
    
    Клонирование ранее созданного гостевой системы:
    
       virt-clone --connect=qemu:///system -o srchost -n newhost -f /path/to/newhost.qcow2
    
    
    А затем поправить в XML файле "<source file='/dev/sdb'/>"
    
    
    Управление окружением.
    
    Заходим в shell virsh:
    
       virsh --connect qemu:///system
    
    Стартуем виртуалную машину:
    
       virsh # start test
    
    Замораживаем состояние виртуальной машины:
    
       virsh # suspend test
    
    Продолжаем выполнение с момента остановки:
    
       virsh # resume test
    
    Список активных виртуальных машин:
    
       virsh # list
    
    Список всех определенных в системе виртуальных машин:
    
       virsh # list --all
    
    Останавливаем виртуальную машину test (эквивалент выполнения shutdown -h now):
    
       virsh # shutdown test
    
    Мгновенно останавливаем виртуальную машину, как при выключении питания:
    
       virsh # destroy test
    
    Удаляем виртуальную машину test из списка (удалем файл конфишурации virsh):
    
       virsh # undefine test
    
    
    Для управления виртуальными машинами с удаленного ПК 10.0.0.1 через GUI
    интерфейс можно использовать:
    
       virt-manager -c qemu+ssh://10.0.0.1/system
    
    на локальной машине:
    
       virt-manager -c qemu:///system
    
    
    Настройка сети.
    
    Настройка эмуляции локальной сети и создания полноценного сетевого соединения
    внутри виртуального окружения.
    
    В хост-окружении создаем интерфейс для бриждинга, в /etc/network/interfaces добавляем:
     
       auto br0
       iface br0 inet static
            address 192.168.0.10
            network 192.168.0.0
            netmask 255.255.255.0
            broadcast 192.168.0.255
            gateway 192.168.0.1
            bridge_ports eth0
            bridge_fd 9
            bridge_hello 2
            bridge_maxage 12
            bridge_stp off
    
    Рестартуем сеть:
    
       sudo /etc/init.d/networking restart
    
    В XML конфигурации гостевой системы правим настройки сети на:
    
      <interface type='bridge'>
          <mac address='00:11:22:33:44:55'/>
          <source bridge='br0'/>
          <model type='virtio'/>
        </interface>
    
     
    ----* Установка ARM-сборки Debian GNU/Linux в qemu (доп. ссылка 1) (доп. ссылка 2) (доп. ссылка 3)   [комментарии]
     
    Перед экспериментами по установке Linux на устройства на базе архитектуры ARM
    (например, Sharp Zaurus,
    Openmoko FreeRunner, планшетные ПК NOKIA, NAS на базе SoC Marvell) вначале
    стоит потренироваться в эмуляторе.
    Кроме того, окружение созданное в эмуляторе удобно использовать 
    для создания и сборки пакетов программ или модулей ядра.
    
    Ставим на рабочую машину qemu. Для debian/ubuntu:
    
       sudo apt-get install qemu
    
    Создаем дисковый образ размером 10Гб для виртуальной машины:
    
       qemu-img create -f qcow hda.img 10G 
    
    Загружаем ядро, initrd и инсталлятор Debian для архитектуры ARM:
    
       wget http://people.debian.org/~aurel32/arm-versatile/vmlinuz-2.6.18-6-versatile 
       wget http://people.debian.org/~aurel32/arm-versatile/initrd.img-2.6.18-6-versatile 
       wget http://ftp.de.debian.org/debian/dists/etch/main/installer-arm/current/images/rpc/netboot/initrd.gz 
    
    Загружаем инсталлятор и устанавливаем Debian по сети, следуя инструкциям программы установки:
    
       qemu-system-arm -M versatilepb -kernel vmlinuz-2.6.18-6-versatile -initrd initrd.gz -hda hda.img -append "root=/dev/ram" 
    
    Запускаем установленную систему:
    
       qemu-system-arm -M versatilepb -kernel vmlinuz-2.6.18-6-versatile -initrd initrd.img-2.6.18-6-versatile \
          -hda hda.img -append "root=/dev/sda1"
    
    Устанавливаем дополнительные программы, например, gcc:
    
       apt-get install gcc
    
    Проверяем:
    
       gcc -dumpmachine
       "arm-linux-gnu"
    
     
    ----* Установка Xen 3.3.1 в Ubuntu, используя модифицированное ядро от Novell (доп. ссылка 1)   [обсудить]
     
    Основная причина использования релиза Xen 3.3.1 в возможность запуска немодифицированного 
    64-разрядного Solaris 10U6 в HVM режиме на SMP машине с несколькими vcpu. 
    Для установки Xen необходимо установить пакеты с openssl, x11, gettext,
    python-devel, bcc, libc6-dev-i386.
    Собираем Xen из исходных текстов:
    
       cd /usr/src
       tar zxvf xen-3.3.1.tar.gz
       cd xen-3.3.1
       make xen
       make install-xen
       make tools
       make install-tools
    
    Собираем hvmloader:
    
       cd tools/firmware
       make
       make install
    
    Устанавливаем из mercurial репозитория модифицированное Linux ядро:
    
       apt-get install build-essential libncurses5-dev gawk mercurial
       mkdir -p ~/build/linux-2.6.27-xen
       cd /usr/src/
       hg clone http://xenbits.xensource.com/ext/linux-2.6.27-xen.hg
       cd linux-2.6.27-xen.hg
       make O=~/build/linux-2.6.27-xen/ menuconfig
       make O=~/build/linux-2.6.27-xen/ -j12
       make O=~/build/linux-2.6.27-xen/ modules_install install
       depmod 2.6.27.5
       mkinitramfs -o /boot/initrd-2.6.27.5.img 2.6.27.5
    
    Настраиваем /etc/init.d/xend и xendomains для автоматической загрузки.
    В настройки grub (/boot/grub/menu.lst) помещаем:
    
       title Xen 3.3 / Ubuntu 8.10, kernel 2.6.27-xen
       kernel /boot/xen-3.3.1.gz
       module /boot/vmlinuz-2.6.27.5 root=/dev/sdb1 ro console=tty0
       module /boot/initrd-2.6.27.5.img
    
    Загружаем систему с новым ядром и проверяем работу Xen:
    
       xm info
    
       host : ServerUbuntu
       release : 2.6.27.5
       ...
    
       brctl show
    
       bridge name bridge id STP enabled interfaces
       eth1 8000.001e8c25cca5 no peth1
       pan0 8000.000000000000 no
    
    Xen профайл для установки Solaris 10U6 в режиме аппаратной виртуализации (HVM):
    
       name = "S10U6"
       builder = "hvm"
       memory = "2048"
       disk = ['phy:/dev/loop0,hdc:cdrom,r','phy:/dev/sdb3,hda,w']
       # disk = ['phy:/dev/sdb3,hda,w']
       vif = [ 'bridge=eth1' ]
       device_model = "/usr/lib64/xen/bin/qemu-dm"
       kernel = "/usr/lib/xen/boot/hvmloader"
       cpuid=[ '1:edx=xxxxxxxxxxxxxx1xxxxxxxxxxxxxxxxx' ]
       vnc=1
       boot="cd"
       usb=1
       usbdevice="tablet"
       vcpus=2
       # serial = "pty" # enable serial console
       on_reboot = 'restart'
       on_crash = 'restart'
    
     
    ----* Настройка сетевого доступа для VirtualBox окружения в Ubuntu/Debian Linux (доп. ссылка 1)   [комментарии]
     
    В простейшем случае работу сети внутри гостевой системы в VirtualBox можно обеспечить через NAT.
    Достаточно выбрать тип эмуляции сетевого интерфейса - NAT, а в гостевой ОС получить IP по DHCP или 
    установить вручную из диапазона 10.0.2.0/24, шлюз 10.0.2.2, DNS 10.0.2.3. 
    
    Для проброса портов из вне можно использовать:
    
       VBoxManage setextradata "freebsd" "VBoxInternal/Devices/e1000/0/LUN#0/Config/guestssh/Protocol" TCP
       VBoxManage setextradata "freebsd" "VBoxInternal/Devices/e1000/0/LUN#0/Config/guestssh/GuestPort" 22
       VBoxManage setextradata "freebsd" "VBoxInternal/Devices/e1000/0/LUN#0/Config/guestssh/HostPort" 2222
    
    где, "freebsd" - это имя виртуальной машины, а e1000 тип эмулируемой карты
    (можно посмотреть в VBox.log).
    Заходя на 2222 порт хостовой машины мы будем переброшены на 22 порт виртуального окружения.
    
    
    Для обеспечения полноценного сетевого окружения для виртуального сервера
    необходимо поднять виртуальный сетевой интерфейс.
    
    
    Устанавливаем пакеты:
    
        sudo apt-get install uml-utilities bridge-utils
    
    Настраиваем бриждинг, редактируем /etc/network/interfaces в случае если IP
    хост-система получает динамически (DHCP):
    
        auto eth0
        iface eth0 inet manual
    
        auto br0
        iface br0 inet dhcp
        bridge_ports eth0 vbox0
    
        # The loopback network interface
        auto lo
        iface lo inet loopback
    
    eth0 - сетевой интерфейс, br0 - создаваемый бридж, vbox0 - имя устройства,
    используемого в VirtualBox
    Если виртуальных окружений несколько, можно написать:
    
        bridge_ports eth0 vbox0 vbox1 vbox2 vbox3 vbox4
    
    В случае со статическим IP настройки примут вид:
    
        auto eth0
        iface eth0 inet manual
    
        auto br0
        iface br0 inet static
        address 192.168.0.100
        netmask 255.255.255.0
        gateway 192.168.0.1
        bridge_ports eth0 vbox0 vbox1
    
        # The loopback network interface
        auto lo
        iface lo inet loopback
    
    При использовании статического IP в eth0, его настройки должны совпадать с br0
    
    Перезапускаем  сетевую подсистему:
    
        sudo /etc/init.d/networking restart
    
    В сетевых настройках VirtualBox определяем виртуальные интерфейсы.
    Для этого редактируем файл /etc/vbox/interfaces:
    
       # Each line should be of the format :
       # <interface name> <user name> [<bridge>]
       vbox0 <your user name> br0
       vbox1 <your user name> br0
    
    Перезапускаем virtualbox для принятия изменений:
    
    Для OpenSource версии:
    
        sudo /etc/init.d/virtualbox-ose restart
    
    Для проприетарной сборки:
    
        sudo /etc/init.d/vboxnet restart
    
    Не забываем убедиться в наличии прав доступа на чтение и запись для
    пользователей группы vboxusers для устройства /dev/net/tun
    
        sudo chown root:vboxusers /dev/net/tun
        sudo chmod g+rw /dev/net/tun
    
    Чтобы права автоматически установились после перезагрузки в
    /etc/udev/rules.d/20-names.rules меняем
    
        KERNEL=="tun", NAME="net/%k"
    
    на
    
        KERNEL=="tun", NAME="net/%k",  GROUP="vboxusers", MODE="0660"
    
    В настройках  VirtualBox для гостевого окружения выбираем "host networking" указав имя 
    созданного виртуального интерфейса, а внутри оргужения ставим IP из
    представленного на интерфейсе диапазона адресов (192.168.0.x).
    
    Вручную отдельный TUN интерфейс без бриджинга можно поднять используя tunctl из
    пакета uml-utilities:
    
       tunctl -t vbox0 -u имя_текущего_пользователя
       ifconfig vbox0 192.168.0.254 up
       route add -host 192.168.0.253 dev vbox0
       echo 1 > /proc/sys/net/ipv4/conf/vbox0/proxy_arp
       arp -Ds 192.168.0.253 eth0 pub
    
    С бриджем:
    
        brctl addbr br0
        ifconfig eth0 0.0.0.0 promisc up
        ifconfig vbox0 0.0.0.0 promisc up
        ifconfig br0 192.168.0.1 netmask 255.255.255.0 up
        brctl stp br0 off
        brctl setfd br0 1
        brctl sethello br0 1
        brctl addif br0 eth0
        brctl addif br0 vbox0
    
     
    ----* Как преобразовать образ виртуальной машины Qemu в VirtualBox и VmWare   [комментарии]
     
    Для преобразования образа виртуальной машины Qemu в вид пригодный для запуска в VirtualBox,
    можно использовать следующие команды:
    
       qemu-img convert qemu.img tmp.bin  
       VBoxManage convertdd tmp.bin virtualbox.vdi
       VBoxManage modifyvdi virtualbox.vdi compact
    
    Для старых версий VirtualBox, нужно было использовать вместо VBoxManage - vditool:
    
       vditool DD virtualbox.vdi tmp.bin  
       vditool SHRINK virtualbox.vdi  
    
    Преобразование qemu образа в формат пригодный для использования в VmWare:
    
       qemu-img convert -6 qemu.img -O vmdk vmware.vmdk
    
    Для преобразования формата VmWare в qemu:
     
       qemu-img convert vmware.vmdk -O qcow2 qemu.img
    
    Для преобразования образа диска или livecd в вид пригодный для использования в qemu:
    
       qemu-img convert -f raw disk.img -O qcow2 qemu.img
       qemu-img convert -f cloop cloop.img -O qcow2 qemu.img
    
     
    ----* OpenVZ в ALT Linux Lite 4.0 (доп. ссылка 1)   Автор: Евгений Прокопьев  [комментарии]
     
    Для запуска OpenVZ необходимо и достаточно сказать:
    
       # apt-get install kernel-image-ovz-smp vzctl
    
    После перезагрузки с новым ядром можно создавать виртуальные машины (VE)
    следующим простым скриптом-оберткой:
    
       #!/bin/sh
    
    # проверяем параметры
    
       if [ -z "$4" ]; then
         echo "Usage : $0 \$VEID \$NAME \$BRANCH \$ARCH"
         exit 1
       fi
    
    # определяем переменные
    
       VE_NAMESERVER="192.168.1.1"
       VE_DOMAIN="local"
       VE_NET="192.168.0."
       VE_REPO="/repo"
       HN_REPO="/lvm/distrib/free/linux/alt"
    
    # создаем VE
    
       vzctl create $1 --ostemplate altlinux-$3-$4
    
    # задаем дефолтные значения для VE
    
       vzctl set $1 --name $2 --ipadd $VE_NET$1 --hostname $2.$VE_DOMAIN \
      --nameserver $VE_NAMESERVER --searchdomain $VE_DOMAIN --onboot yes --save
    
    # создаем каталог с репозитарием внутри VE
    
       mkdir /var/lib/vz/private/$1/repo
    
    # создаем скрипт, который будет монтировать репозитарий из HN
    
       cat > /etc/vz/conf/$1.mount <<END
    
       #!/bin/sh
    
       . /etc/vz/vz.conf
    
       mount -n -o bind $HN_REPO/$3 \$VE_ROOT/repo
       END
    
    # делаем скрипт исполняемым
    
       chmod 700 /etc/vz/conf/$1.mount
    
    # настроиваем apt
    
       cat > /var/lib/vz/private/$1/etc/apt/sources.list <<END
       rpm file:///repo/branch/ $4 classic
       rpm file:///repo/branch/ noarch classic
       END
    
    Многое здесь прибито гвоздями: например, предполагается, что в /lvm/distrib/free/linux/alt 
    находятся копии branch/4.0 и branch/4.1, а в /var/lib/vz/template/cache/ - 
    собранные из бранчей с помощью Hasher шаблоны VE:
    
       altlinux-4.0-i586.tar.gz
       altlinux-4.0-x86_64.tar.gz
       altlinux-4.1-i586.tar.gz
       altlinux-4.1-x86_64.tar.gz
    
    В шаблонах находятся basesystem, apt, sysklogd, etcnet, glibc-nss, glibc-locales, 
    netlist, passwd, su, openssh-server, vim-console, mc, less, man и все, что было
    вытянуто по зависимостям.
    
    Предполагается, что свежесозданные VE будут запущены с помощью vzctl start и
    первоначально настроены
    с помощью vzctl enter (т.е. будут созданы необходимые пользователи и пароли/ключи) - 
    далее с ними можно будет работать обычным образом по ssh, сверяясь по мере
    надобности с полезными советами.
    
     
    ----* Настройка сети для виртуального окружения на основе KVM (доп. ссылка 1)   [комментарии]
     
    Имеется машина с Ubuntu Linux, имеющая один сетевой интерфейс. При помощи гипервизора KVM создано
    два гостевых окружения - debian01 и debian02. Задача организовать сетевую связь
    (виртуальная LAN) между
    гостевыми системами и корневой системой и обеспечить выход в интернет, через
    сетевой интерфейс корневой системы.
    
    Настройка корневой системы.
    
    Первым делом нужно создать виртуальный Ethernet коммутатор на базе пакета VDE,
    при помощи которого будет создан виртуальный интерфейс tap0, через который будет организована связь
    между гостевыми окружениями.
    Создаем интерфейс:
       sudo vde_switch -tap tap0 -daemon
    
    Проверяем:
       ifconfig tap0
    
       tap0      Link encap:Ethernet  direcci&#243;nHW 00:ff:1b:e7:76:46
       DIFUSI&#211;N MULTICAST  MTU:1500  M&#233;trica:1
       RX packets:1 errors:0 dropped:0 overruns:0 frame:0
       TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
       colisiones:0 txqueuelen:500
       RX bytes:53 (53.0 B)  TX bytes:0 (0.0 B)
    
    Привязываем адреса виртуальной сети (192.168.254.0/255):
       ifconfig tap0 192.168.254.254 netmask 255.255.255.0
    
    для гостевых окружений, адрес 192.168.254.254 будет использоваться в роли шлюза.
    
    
    Настройка гостевых систем.
    
    Настраиваем в гостевом окружении сетевой интерфейс eth0 (выделяем первому - IP 192.168.254.1,
    второму - 192.168.254.2 и т.д.)
    Содержимое /etc/network/interfaces
    
       # loopback
       auto lo
       iface lo inet loopback
    
       allow-hotplug eth0
       #iface eth0 inet dhcp
       iface eth0 inet static
       address 192.168.254.1
       netmask 255.255.255.0
       network 192.168.254.0
       broadcast 192.168.254.255
       gateway 192.168.254.254
    
    
    Для предотвращения виртуальных окружений под одним MAC адресом, меняем MAC виртуальных карт:
    
       sudo aptitude install macchanger
    
    Создаем скрипт /etc/network/if-pre-up.d/macchange, меняющий MAC
    
       #!/bin/sh
       if [ ! -x /usr/bin/macchanger ]; then
          exit 0
       fi
       /usr/bin/macchanger -a eth0
    
    Перезапускаем гостевые окружения (вместо $IMAGE подставляем путь к окружению):
       sudo /usr/bin/vdeq /usr/bin/kvm $IMAGE -m 512 -localtime -k es
    
    
    Настройка выхода гостевых систем в интернет.
    
    Проверяем на корневой системе, включен ли форвардинг пакетов между интерфейсами:
       sysctl net.ipv4.ip_forward
    
    Если выдало 0, то форвардинг отключен, включаем:
       sudo -w sysctl net.ipv4.ip_forward=1
    
    и сохраняем в /etc/sysctl.conf строку
       net.ipv4.ip_forward = 1
    
    В скрипте инициализации, после поднятия tap0 интерфейса, включаем трансляцию адресов:
    
       sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
    
     
    ----* Запуск NetBSD в qemu под FreeBSD (доп. ссылка 1)   Автор: Anton Yuzhaninov  [комментарии]
     
    Недавно понадобилось посмотреть на NetBSD. Сходу в сети не нашлось описания как это можно сделать, 
    поэтому может кому то пригодится описание того, как это получилось у меня.
    
    1. Создаем образ, на который будет установлена система:
    
      qemu-img create -f qcow2 netbsd.img 4G
    
    2. Подгружаем модуль aio
    
       sudo kldload aio
    
    3. Скачиваем iso-шку с дистрибутивом и загружаем с неё виртуальную машинку:
    
       qemu -m 256 -curses -hda netbsd.img -cdrom i386cd-4.0.iso -boot d
    
    Далее netbsd устанавливается так же как на обычный PC.
    
    4. Для работы сети внутри виртуальной машины можно сделать бридж между
    физическим интерфейсом и tap:
    
       sudo ifconfig tap create
       sudo ifconfig bridge create
       sudo ifconfig bridge0 addm tap0 addm re0 up
       sudo sysctl net.link.tap.up_on_open=1
       sudo sysctl net.link.tap.user_open=1
    
    Чтобы запускать qemu из под пользователя надо дать ему права на /dev/tap0
    
    4. Без отключения ACPI NetBSD не захотела видеть ни одну из сетевух, которые эмулирует qemu, 
    поэтому ACPI пришлось отключить:
    
       qemu -m 256 -curses -hda netbsd.img -no-acpi -net nic -net tap
    
     
    ----* Решение проблемы с ошибкой при загрузке снапшота VirtualBox (доп. ссылка 1)   Автор: Heckfy  [комментарии]
     
    Бывает, виртуальная машина отказывается загружаться со следующей ошибкой:
    
       Unable to restore the virtual machine's saved state from 
       'M:\VM\Machines\Windows Xp Sviluppo\Snapshots\{ce28664d-45f3-46dd8468-9ba91a689e7b}.sav'. 
       It may be damaged or from an older version of VirtualBox. Please discard the 
       saved state before starting the virtual machine. VBox status code: -1829 (VERR_SSM_UNEXPECTED_DATA).
    
    Для решения проблемы требуется восстановить условия, в которых находилась виртуальная машина: 
    сетевые папки (в моем случае, это каталог /media/ в линуксе и всё дерево каталогов, 
    доступных виртуальной машине на тот момент), компакт-диски, Flash и прочее съемное.
    
     
    ----* Установка FreeBSD в окружении Virtualbox   [комментарии]
     
    FreeBSD 6.3 в Virtualbox 1.6 и 2.0 (сборка для Ubuntu Linux 7.10)  запустить не удалось 
    (были испробованы всевозможные  комбинации конфигурации VirtualBox),
    наблюдается крах в процессе загрузки ядра.
    
    FreeBSD 7.0 был удачно установлен и использован в Virtualbox 1.6.x, но в VirtualBox 2.0 
    перестал работать режим аппаратной виртуализации VT-x/AMD-V, при включении данной 
    опции bootloader вываливается в бесконечную демонстрацию регистровых дампов. 
    Пришлось откатиться обратно до  Virtualbox 1.6.6.
    
    Далее, привожу особенности установки FreeBSD 7.0 в Virtualbox.
    
    Во время установки FreeBSD в виртуальном окружении Virtualbox, процесс зависает 
    во время отображения меню bootloader'а.
    Чтобы зависания не произошло нужно в параметрах VirtualBox запретить использование VT-x/AMD-V. 
    В форумах также можно найти жалобы на зависание в процессе загрузки ядра,
    решаемые выключением ACPI  в VirtualBox.
    
    После завершения установки, загрузившись в новую гостевую систему, меняем /boot/loader.conf:
    
       kern.hz="50"
       beastie_disable="YES"
    
    Т.е. уменьшаем частоту генерации прерываний от таймера, чтобы виртуальная машина 
    не грузила CPU хост-системы и запрещаем отображение меню загрузчика, на котором 
    система повисает при включении VT-x/AMD-V.
    
    Включаем в настройках VT-x/AMD-V. Тип эмулируемого сетевого адаптера нужно
    выбрать PCNet-PCI II или Intel Pro,
    тот что ставится по умолчанию (PCNet-Fast III) не работает во FreeBSD.
    
    Тип эмуляции сетевого интерфейса выбираем NAT, а в FreeBSD получаем адрес по DHCP или 
    устанавливаем IP из диапазона 10.0.2.0/24, шлюз 10.0.2.2, DNS 10.0.2.3. 
    Внимание, ping в NAT режиме не работает, проверять приходится через telnet.
    
    Для того чтобы в гостевую систему можно было зайти по SSH, нужно перебросить 22 порт из вне. 
    Запускаем в консоли хост-системы:
    
       VBoxManage setextradata "freebsd" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/guestssh/Protocol" TCP
       VBoxManage setextradata "freebsd" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/guestssh/GuestPort" 22
       VBoxManage setextradata "freebsd" "VBoxInternal/Devices/pcnet/0/LUN#0/Config/guestssh/HostPort" 2222
    
    где, "freebsd" - это имя виртуальной машины, а pcnet тип эмулируемой карты.
    
    После перезапуска гостевого окружения, заходя на 2222 порт хостовой машины мы будем 
    переброшены на 22 порт виртуального окружения.
    
       ssh -p2222 localhost
    
    В форумах советуют создать для FreeBSD образ диска фиксированного размера, 
    но я использую динамически расширяемый образ и проблем не наблюдаю.
    
     
    ----* Создание initrd образа для гостевого Xen окружения в CentOS   [комментарии]
     
    В CentOS 5, при установке пакета kernel-xen с ядром, по умолчанию создается initrd образ для Dom0.
    Для использования данного ядра в гостевом окружении необходимо создать initrd 
    с поддержкой сетевого и блочного xen модулей, иначе ядро в гостевой ФС не сможет 
    смонтировать корневую ФС на дисковом разделе.
    
    Имеем ядро kernel-xen-2.6.18-53.1.13.el5
    
    Создаем initrd:
       /sbin/mkinitrd --with=xennet --preload=xenblk /boot/initrd-centos5-xen.img 2.6.18-53.1.13.el5xen
    
    Пример xen профайла vps3:
    
    kernel = "/boot/vmlinuz-2.6.18-53.1.21.el5xen"
    ramdisk = "/boot/initrd-centos5-xen.img"
    memory = 1024
    name = "vps3"
    cpus = "0"        # all vcpus run on CPU0
    vcpus = 1
    vif = [ '', 'mac=00:16:3E:00:00:02, bridge=virbr1, vifname=eth2, ip=192.168.122.2' ]
    disk = [ 'phy:/dev/mapper/sil_ahajbjcdabeip7,sda1,w' ]
    root = "/dev/sda1 ro"
    extra = "4"
    
     
    ----* Установка OpenSolaris2008/05 DomU в Xen 3.2.1 CentOS 5.1 Dom0 (64-bit) (доп. ссылка 1)   Автор: Boris Derzhavets  [комментарии]
     
    Вариант 1.
    
    Установка OpenSolaris2008/05 HVM DomU в Xen 3.2.1 CentOS 5.1 Dom0 (64-bit) 
    на машине с процессором поддерживающим технологии Intel VT или AMD-V
    
    Определяем, поддерживаем ли процессор аппаратную виртуализацию:
    Intel:
      grep -i vmx /proc/cpuinfo 
    
    AMD:
      grep -i svm /proc/cpuinfo 
    
    Активирован ли HVM в BIOS (также можно поискать по ключам VT, VMX, SVM):
      grep -i hvm /sys/hypervisor/properties/capabilities 
    
    Создаем слепок установочного DVD диска с OpenSolaris 2008/05:
    
       # dd if=/dev/hda of=/usr/lib/xen-solaris/os200805.iso
    
    Создаем Xen профайл для установки OpenSolaris2008/05:
    
       [root@dhcppc3 vm]# cat OS0805.hvm
       name = "OS200805HVM"
       builder = "hvm"
       memory = "1024"
       disk =     ['phy:/dev/sdb11,ioemu:hda,w','file:/usr/lib/xen-solaris/os200805.iso,hdc:cdrom,r']
       vif = [ 'type=ioemu,bridge=eth0' ]
       device_model = "/usr/lib64/xen/bin/qemu-dm"
       kernel = "/usr/lib/xen/boot/hvmloader"
       vnc=1
       boot="d"
       vcpus=1
       serial = "pty" # enable serial console
       on_reboot   = 'restart'
       on_crash    = 'restart'
    
    Запускаем установку в гостевом окружении Xen:
    
       # xm create OS200805.hvm
    
    Подключаем VNC клиент для управления установкой:
    
       # vncviewer localhost:0
    
    
    После установки меняем Xen профайл на рабочий и запускаем его:
    
       [root@dhcppc3 vm]# cat OS0805RT.hvm
       name = "OS200805HVM"
       builder = "hvm"
       memory = "1024"
       disk = ['phy:/dev/sdb11,ioemu:hda,w']
       vif = [ 'type=ioemu,bridge=eth0' ]
       device_model = "/usr/lib64/xen/bin/qemu-dm"
       kernel = "/usr/lib/xen/boot/hvmloader"
       vnc=1
       boot="c"
       vcpus=1
       serial = "pty" # enable serial console
       on_reboot   = 'restart'
       on_crash    = 'restart'
      
    Редактируем конфигурацию Grub (/rpool/boot/grub/menu.lst) в Solaris, для загрузки 64-битного ядра.
    
    
    Вариант 2.
    
    Установка OpenSolaris2008/05 DomU в Xen 3.2.1 CentOS 5.1 Dom0 (64-bit) в режиме
    паравиртуализации, используя модифицированное ядро Solaris
    
    Создаем слепок установочного DVD диска с OpenSolaris 2008/05:
    
       # dd if=/dev/hda of=/usr/lib/xen-solaris/os200805.iso
    
    Копируем 64-битное ядро xen-solaris и x86.microroot в хостовое окружение (Dom0):
    
       mkdir -p /mnt01/tmp
       mount -o loop,ro os200805.iso  /mnt01/tmp
       cp /mnt01/tmp/boot/x86.microroot /usr/lib/xen-solaris/x86.microroot
       cp /mnt01/tmp/boot/platform/i86xpv/kernel/amd64/unix  /usr/lib/xen-solaris/unix-0805
       umount /mnt01/tmp
     
    Для установки используем Xen профайл:
    
       name = "OpenSolaris"
       vcpus = 1
       memory = "1024"
       kernel = "/usr/lib/xen-solaris/unix-0805"
       ramdisk = "/usr/lib/xen-solaris/x86.microroot"
       extra = "/platform/i86xpv/kernel/amd64/unix -kd - nowin -B  install_media=cdrom"
       disk = ['file:/usr/lib/xen-solaris/os200805.iso,6:cdrom,r','phy:/dev/sdb8,0,w']
       vif = ['bridge=eth0']
       on_shutdown = "destroy"
       on_reboot = "destroy"
       on_crash = "destroy"
    
    Во время загрузки виртуальной машины набираем:
    
       Welcome to kmdb
       Loaded modules: [ unix krtld genunix ]
       [0]> gnttab_init+0xce/W 403
       gnttab_init+0xce: 0x3 = 0x403
       [0]> :c
     
    Входим в систему как jack/jack и выполняем установку LiveCD на виртуальный жесткий диск. 
    
    Когда установка будет завершена не производите перезагрузку, а откройте root-терминал и выполните:
    
    
       # mdb -w /a/platform/i86xpv/kernel/amd64/unix
       > gnttab_init+0xce?W 403
       unix`gnttab_init+0xce: 0x403 = 0x403
       > $q
    
       # /usr/bin/scp -S /usr/bin/ssh /a/platform/i86xpv/kernel/amd64/unix \
    > IP-ADDRESS-Dom0:/usr/lib/xen-solaris/unix-0805
    
       # /usr/bin/scp -S /usr/bin/ssh /a/platform/i86pc/amd64/boot_archive \
    > IP-ADDRESS-Dom0:/usr/lib/xen-solaris/boot_archive
    
       bash-3.2# shutdown -y -i0 -g0
      
    После установки меняем Xen профайл на рабочий:
    
       name = "OpenSolaris"
       vcpus = 1
       memory = "1024"
       kernel = "/usr/lib/xen-solaris/unix-0805"
       ramdisk = "/usr/lib/xen-solaris/boot_archive"
       extra = "/platform/i86xpv/kernel/amd64/unix -B zfs-bootfs=rpool/27"
       disk = ['file:/usr/lib/xen-solaris/os200805.iso,6:cdrom,r','phy:/dev/sdb8,0,w']
       vif = ['bridge=eth0']
       on_shutdown = "destroy"
       on_reboot = "destroy"
       on_crash = "destroy"
      
    
     
    ----* Установка и использование OpenVZ в Debian GNU/Linux (доп. ссылка 1)   Автор: Falko Timme  [комментарии]
     
    Добавляем в /etc/apt/sources.list репозиторий с OpenVZ:
    
       deb http://download.openvz.org/debian-systs etch openvz
    
    Далее:
    
       wget -q http://download.openvz.org/debian-systs/dso_archiv_signing_key.asc -O- | apt-key add - 
       apt-get update
    
    Устанавливаем ядро с OpenVZ. 
    
    В репозитории доступны ядра версий 2.6.18 и 2.6.24 в сборках 486, 686,
    686-bigmem (до 63 Гб ОЗУ) и amd64.
    
       apt-get install fzakernel-2.6.18-686-bigmem
       update-grub
    
    Устанавливаем утилиты и минимальный образ гостевой системы:
    
       apt-get install vzctl vzquota vzprocps vzdump
       apt-get install vzctl-ostmpl-debian
    
    Для работы сети в VPS проверяем настройки /etc/sysctl.conf:
    
       net.ipv4.conf.all.rp_filter=1
       net.ipv4.conf.default.forwarding=1
       net.ipv4.conf.default.proxy_arp = 0
       net.ipv4.ip_forward=1
    
    Перечитываем настойки: sysctl -p
    
    Если IP виртуальной машины находится вне подсети, используемой на хост-машине:
    В /etc/vz/vz.conf ставим:
    
       NEIGHBOUR_DEVS=all
    
    
    Перезагружаем машину с новым OpenVZ ядром и приступаем к поднятию виртуального окружения.
    
    Создаем виртуальную машину с ID 101 на основе ранее загруженного шаблона (vzctl-ostmpl-debian):
    
       vzctl create 101 --ostemplate debian-4.0-i386-minimal --config vps.basic
    
    Включаем автоматиеческий запуск созданного VPS на стадии загрузки системы:
    
       vzctl set 101 --onboot yes --save
    
    Назначаем VPS имя хоста и IP:
    
       vzctl set 101 --hostname test.example.com --save
       vzctl set 101 --ipadd 1.2.3.101 --save
    
    Ограничиваем число открытых сокетов, число процессов и объем памяти:
    
       vzctl set 101 --numothersock 100 --save
       vzctl set 101 --numtcpsock 100 --save
       vzctl set 101 --numproc 150 --save
       vzctl set 101 --vmguarpages 65536 --save # гарантированный объем 256Мб, в блоках по 4Кб
       vzctl set 101 --privvmpages 131072 --save # максимальный объем 512Мб, в блоках по 4Кб
    
    Список возможных ограничений - http://wiki.openvz.org/UBC_parameters_table
    
    Прописываем DNS серверы для VPS:
    
       vzctl set 101 --nameserver 213.133.98.98 --nameserver 213.133.99.99 \
         --nameserver 213.133.100.100 --nameserver 145.253.2.75 --save
    
    Можно вместо вызова vzctl напрямую отредактировать файл конфигурации /etc/vz/conf/101.conf
    
    
    Запускаем созданную VPS:
    
       vzctl start 101
    
    Устанавливаем пароль суперпользователя VPS, запустив внутри команду passwd:
    
       vzctl exec 101 passwd
    
    Входим в shell VPS (можно сразу зайти по SSH):
    
       vzctl enter 101
    
    Останавливаем VPS:
    
       vzctl stop 101
    
    Удаляем VPS с жесткого диска:
    
       vzctl destroy 101
    
    Просматриваем список VPS и их статус:
    
       vzlist -a
    
    Просмотр ресурсов доступных внутри VPS:
    
       vzctl exec 101 cat /proc/user_beancounters 
    
    
    Подробнее см. http://wiki.openvz.org/
    
     
    ----* Как в Linux примонтировать образ QEMU диска   [комментарии]
     
    mount -o loop,offset=32256 qemu_image.img /mnt/qemu_image
    
     
    ----* Откуда берется steal внутри виртуальных машин и что с этим делать (доп. ссылка 1)   Автор: Mail.Ru Cloud Solutions  [комментарии]
     
    CPU steal time - это время, в течение которого виртуальная машина не получает
    ресурсы процессора для своего выполнения. Это время считается только в гостевых
    операционных системах в средах виртуализации.
    
    Что такое steal
    
    Steal  - это метрика, указывающая на нехватку процессорного времени для
    процессов внутри виртуальной машины. Как описано в патче ядра KVM, steal -
    это время, в течение которого гипервизор выполняет другие процессы на хостовой
    операционной системе, хотя он поставил процесс виртуальной машины в очередь на
    выполнение. То есть steal считается как разница между временем, когда процесс
    готов выполниться, и временем, когда процессу выделено процессорное время.
    
    Метрику steal ядро виртуальной машины получает от гипервизора. При этом
    гипервизор не уточняет, какие именно другие процессы он выполняет, просто
    "пока занят, тебе времени уделить не могу". На KVM поддержка подсчёта
    steal добавлена в патчах. Ключевых моментов здесь два:
    
    1.   Виртуальная машина узнает о steal от гипервизора. То есть, с точки зрения
    потерь, для процессов на самой виртуалке это непрямое измерение, которое может
    быть подвержено различным искажениям.
    
    2.   Гипервизор не делится с виртуалкой информацией о том, чем он занят -
    главное, что он не уделяет время ей. Из-за этого сама виртуалка не может
    выявить искажения в показателе steal, которые можно было бы оценить по
    характеру конкурирующих процессов.
    
    Как вычислить steal
    
    По сути, steal считается как обычное время утилизации процессора. В ядре
    добавляется ещё один счетчик непосредственно для процесса KVM (процесса
    виртуальной машины), который считает длительность пребывания процесса KVM в
    состоянии ожидания процессорного времени. Счетчик берет информацию о процессоре
    из его спецификации и смотрит, все ли его тики утилизированы процессом
    виртуалки. Если все, то считаем, что процессор занимался только процессом
    виртуальной машины. В ином случае информируем, что процессор занимался чем-то
    еще, появился steal.
    Подробнее читайте в статье Brendann Gregg.
    
    Как мониторить steal
    
    Мониторить steal внутри виртуальной машины можно как любую другую процессорную
    метрику. Главное, чтобы виртуалка была на Linux. Windows  такую информацию не предоставляет.
    
    Сложность возникает при попытке получить эту информацию с гипервизора. Можно
    попробовать спрогнозировать steal на хостовой машине, например, по параметру
    Load Average (LA) - усредненного значения количества процессов, ожидающих в
    очереди на выполнение. Методика подсчета этого параметра непростая, но в целом
    пронормированный по количеству потоков процессора LA > 1 указывает на
    перегрузку Linux-сервера.
    
    Чего же ждут все эти процессы? Очевидный ответ - процессора. Но иногда
    процессор свободен, а LA зашкаливает. На самом деле, процессы могут ожидать
    окончания любой блокировки, как физической, связанной с устройством
    ввода/вывода, так и логической, например мьютекса. Туда же относятся блокировки
    на уровне железа (того же ответа от диска) или логики (так называемых
    блокировочных примитивов).
    
    Ещё одна особенность LA в том, что оно считается как среднее значение по ОС,
    причём не меньше, чем за минуту. Например, 100 процессов конкурируют за один
    файл, тогда LA=50. Такое большое значение, казалось бы, говорит, что ОС плохо.
    Но для криво написанного кода это может быть нормой - плохо только ему, а
    другие процессы не страдают. Из-за этого усреднения (причём не меньше, чем за
    минуту), определение чего-либо по LA может закончиться весьма неопределенными
    результатами в конкретных случаях.
    
    Почему появляется steal и что делать
    
    Остановимся на основных причинах появления steal, с которыми мы столкнулись при
    работе с облачной платформой MCS, и способах борьбы с ними.
    
    Переутилизация. Самое простое и частое - много запущенных виртуальных машин,
    большое потребление процессора внутри них, большая конкуренция, утилизация по
    LA больше 1 (в нормировке по процессорным тредам). Внутри всех виртуалок всё
    тормозит. Steal, передаваемый с гипервизора, также растёт, надо
    перераспределять нагрузку или кого-то выключать.
    При этом нужно учитывать, что соотношение нагрузки на гипервизоре и steal
    внутри виртуальной машины не всегда однозначно взаимосвязаны. Обе оценки steal
    могут быть ошибочными в конкретных ситуациях при разных нагрузках.
    
    Паравиртуализация против одиноких инстансов. На гипервизоре одна единственная
    виртуалка, она потребляет небольшую его часть, но дает большую нагрузку по
    вводу/выводу, например по диску. И откуда-то в ней появляется небольшой steal,
    до 10%.
    
    Тут дело как раз в блокировках на уровне паравиртуализированных драйверов.
    Внутри виртуалки создается прерывание, оно обрабатывается драйвером и уходит в
    гипервизор. Из-за обработки прерывания на гипервизоре для виртуалки это
    выглядит как отправленный запрос, она готова к исполнению и ждёт процессора, но
    процессорного времени ей не дают. Виртуалка думает, что это время украдено.
    
    Это происходит в момент отправки буфера, он уходит в kernel space гипервизора,
    и мы начинаем его ждать. Хотя, с точки зрения виртуалки, он должен сразу
    вернуться. Следовательно, по алгоритму расчета steal это время считается
    украденным. Скорее всего, в этой ситуации могут быть и другие механизмы
    (например, обработка ещё каких-нибудь sys calls), но они не должны сильно отличаться.
    
    Небольшой steal можно считать нормой (даже и без паравиртуализации, с учётом
    нагрузки внутри виртуалки, особенностей нагрузки соседей, распределения
    нагрузки по тредам и прочего). Однако важно обращать внимание на то, как себя
    чувствуют приложения внутри виртуалок.
    
    Шедулер против высоконагруженных виртуалок. Когда одна виртуалка страдает от
    steal больше других, это связано с шедулером (распределением ресурсов между
    процессами) - чем сильнее процесс нагружает процессор, тем скорее шедулер
    его выгонит, чтобы остальные тоже могли поработать. Если виртуалка потребляет
    немного, она почти не увидит steal: её процесс честно сидел и ждал, ему дадут
    время. Если виртуалка дает максимальную нагрузку по всем своим ядрам, её чаще
    выгоняют с процессора и не дают много времени. Шедулер плохо относится к
    процессам, которые много просят. Большие виртуалки - зло.
    
    Низкий LA, но есть steal. LA примерно 0,7 (то есть, гипервизор, кажется
    недозагружен), но внутри отдельных виртуалок наблюдается steal:
    
    1.   Уже описанный выше вариант с паравиртуализацией. Виртуалка может получать
    метрики, указывающие на steal, хотя у гипервизора всё хорошо. По результатам
    наших экспериментов, такой вариант steal не превышает 10 % и не должен
    оказывать существенного влияния на производительность приложений внутри виртуалки.
    
    2.   Неверно считается LA. Точнее, в каждый конкретный момент он считается
    верно, но при усреднении получается заниженным. Например, если одна виртуалка
    на треть гипервизора потребляет все свои процессоры ровно полминуты, LA за
    минуту на гипервизоре будет 0,15; четыре такие виртуалки, работающие
    одновременно, дадут 0,6. А то, что полминуты на каждой из них был steal под 25
    % по LA, уже не вытащить.
    
    3.   Из-за шедулера, решившего, что кто-то слишком много ест, и пусть он
    подождет, пока я займусь другими важными системными вещами. В итоге одни
    виртуалки не видят никаких проблем, а другие испытывают серьезную деградацию производительности.
    
    Другие искажения
    
    Есть другие причины для искажений честной отдачи процессорного времени на
    виртуалке. Например, сложности в расчёты вносят гипертрединг и NUMA. Они
    запутывают выбор ядра для исполнения процесса, потому что шедулер использует
    коэффициенты - веса, которые при переключении контекста выполняют
    усложнённый подсчёт.
    
    Бывают искажения из-за технологий типа турбобуста или, наоборот, режима
    энергосбережения, которые при подсчёте утилизации могут искусственно повышать
    или понижать частоту или даже квант времени на сервере. Включение турбобуста
    уменьшает производительность одного процессорного треда из-за увеличения
    производительности другого. В этот момент информация об актуальной частоте
    процессора виртуальной машине не передается, и она считает, что её время кто-то
    тырит (например, она запрашивала 2 ГГц, а получила вдвое меньше).
    
    В общем, причин искажений может быть много. Чтобы выяснить steal в конкретной
    системе, исследуйте различные варианты, собирайте метрики, тщательно их
    анализируйте и продумывайте, как равномерно распределять нагрузку. От любых
    кейсов возможны отклонения, которые надо подтверждать экспериментально или
    смотреть в отладчике ядра. Начать лучше с книг, на которые я дал линки выше, и
    съёма статистики с гипервизора утилитами типа perf, sysdig, systemtap, коих десятки.
    
     
    ----* Установка Xen 4.0.0 в Ubuntu Linux 10.04 (доп. ссылка 1)   [комментарии]
     
    В заметке показано как запустить Xen 4.0.0 (dom0) с Linux ядром 2.6.32.10
    поверх 64-разрядной сборки Ubuntu 10.04-beta.
    
    Устанавливаем необходимые для сборки пакеты:
    
       sudo aptitude install build-essential libncurses5-dev dpkg-dev debhelper fakeroot
    
    Загружаем Linux ядро с dom0-патчами:
    
       sudo -s
       cd /usr/src
       git clone git://git.kernel.org/pub/scm/linux/kernel/git/jeremy/xen.git linux-2.6-xen
       cd linux-2.6-xen
       git checkout -b xen/stable origin/xen/stable
    
    Копируем файл с параметрами конфигурации ядра:
    
       curl http://opennet.ru/soft/xen40_config.txt > /usr/src/linux-2.6-xen/.config
    
    Анализируем различия с базовым файлом конфигурации Ubuntu и при необходимости вносим изменения:
    
       diff /boot/config-2.6.32-17-generic /usr/src/linux-2.6-xen/.config | vim -
    
    Собираем ядро:
    
       make menuconfig # включаем поддержку dom0 и Xen
       make
       chmod g-s /usr/src -R  # для того чтобы избежать ошибки "dpkg-deb: control directory has bad permissions..."
       make deb-pkg
    
    Собираем и устанавливаем пакет с ядром, настраиваем initramfs и grub:
    
       dpkg -i ../linux-image*2.6.32.10*.deb
       depmod 2.6.32.10
       update-initramfs -c -k 2.6.32.10
       update-grub
       echo "xen-evtchn" >> /etc/modules
    
    Готовим окружение для сборки
    
       apt-get build-dep xen-3.3
       aptitude install uuid-dev iasl texinfo
    
    Загружаем Xen
    
       cd /usr/src
       hg clone -r 4.0.0 http://xenbits.xensource.com/xen-unstable.hg
       cd xen-unstable.hg
    
    Собираем 
    
       make xen
       make tools
       make stubdom
       make install-xen
       make install-tools PYTHON_PREFIX_ARG=
       make install-stubdom
    
       update-rc.d xend defaults 20 21
       update-rc.d xendomains defaults 21 20
    
    Настраиваем Grub2 через создание файла /etc/grub.d/40_custom:
    
       #!/bin/sh
       exec tail -n +3 $0
         menuentry "Xen 4.0.0-rc8 / Ubuntu 10.4 kernel 2.6.32.10 pvops" {
         insmod ext2
         set root=(hd0,1)
         multiboot (hd0,1)/xen-4.0.0.gz dummy=dummy
         module (hd0,1)/vmlinuz-2.6.32.10 dummy=dummy root=/dev/mapper/HyperDeskVG01-tcmc-dell-lucid ro
         module (hd0,1)/initrd.img-2.6.32.10
       }
    
    Не забудьте изменить значение параметра "root=" на корневой раздел текущей системы.
    
    Обновляем параметры Grub:
    
       update-grub
    
    Перезагружаем систему с dom0-ядром:
    
       reboot
    
    Проверяем работает ли Xen:
    
       xm list
       xm info
    
    Если нет, пытаемся выполнить:
    
       /etc/init.d/xendomains stop
       /etc/init.d/xend stop
       /etc/init.d/xend start
       /etc/init.d/xendomains start
    
     

       Помещение программ в chroot

    ----* Работа с 32- и 64-разрядными chroot на примере Debian   Автор: Павел Отредиез  [комментарии]
     
    Я работаю в Debian testing ARCH=i386 с amd64 битным ядром. 64-битное ядро
    позволяет запускать и 64-битные программы и 32-битные.
    
       uname -ar
       Linux mainpc.tinyware.sytes.net 5.10.43-tinyware-amd64 #1 SMP Fri Jun 11 00:52:31 UTC 2021 x86_64 GNU/Linux
    
    
    32-битный userspace уже есть  в основной системе, хочется иметь 64-битный
    userspace как можно более прозрачно.
    
    Для этого подготовлен chroot:
    
       sudo mkdir /opt/debian64
       sudo debootstrap --arch amd64 stable /opt/debian64/ http://mirror.yandex.ru/debian/
    
    Надо сделать chroot полноценным, пробросив в него нужные файловые системы, для
    этого в /etc/fstab добавим
    
       /proc	/opt/debian64/proc	bind	bind,auto
       /dev	/opt/debian64/dev	bind	bind,auto
       /dev/pts	/opt/debian64/dev/pts	bind   bind,auto
       /sys	/opt/debian64/sys	bind	bind,auto
       /tmp	/opt/debian64/tmp	bind	bind,auto
       /home	/opt/debian64/home	bind	bind,auto
       /run	/opt/debian64/run	bind	bind,auto
    
    Теперь в него легко можно чрутиться от рута и это полноценное окружение.
    
       sudo chroot /opt/debian64
    
    Но хотелось бы запускать программы прямо от текущего пользователя. Для этого
    
       sudo cp /usr/sbin/chroot /usr/bin/uchroot
       sudo setcap CAP_SYS_CHROOT+ep /usr/bin/uchroot
    
    Теперь можно запускать программы из под обыкновенного пользователя
    
       $ uchroot /opt/debian64
    
    или сразу команду (можно добавить в ярлык)
    
       $ uchroot /opt/debian64 tuxguitar
    
    
    Так же для красоты можно скопировать в /opt/debian64 файлы /etc/passwd
    /etc/shadow /etc/group /etc/gshadow
    
     
    ----* Как сменить корень документов в Apache/nginx в CentOS 7 и RHEL 7 с SELinux   [комментарии]
     
    По умолчанию для Apache, nginx  и других http-серверов при использовании
    SELinux в CentOS 7 и RHEL 7 область видимости ограничена директорией /var/www.
    Для смены корня документов на /home/site следует включить новые директории в
    правила httpd_sys_content_t и httpd_sys_script_exec_t.
    
    
    Включаем временно:
       chcon -R -t httpd_sys_content_t /home/site
       chcon -R -t httpd_sys_script_exec_t /home/site/cgi-bin
    
    Включаем постоянно:
       semanage fcontext -a -t httpd_sys_content_t "/home/site(/.*)?"
       semanage fcontext -a -t httpd_sys_script_exec_t "/home/site/cgi-bin(/.*)?"
       restorecon -r -v /home/site
    
    
    Отслеживаем возможные проблемы в /var/log/audit/audit.log и при необходимости
    строим свои правила обхода. В качестве шаблона можно использовать результат
    работы утилиты audit2allow:
    
       audit2allow -M policy_name -i /var/log/audit/audit.log 
       semodule -i policy_name.pp
    
    
    Не забываем открыть доступ к сетевым портам на межсетевом экране:
       firewall-cmd --permanent --add-port=80/tcp
       firewall-cmd --permanent --add-port=443/tcp
    
     
    ----* Запуск Skype в изолированном окружении Apparmor (доп. ссылка 1)   [комментарии]
     
    Для защиты от потенциального доступа закрытого приложения Skype к данным других
    программ можно организовать выполнение Skype в изолированном окружении.
    
    Создаём профиль Apparmor на основе тестового запуска приложения:
    
       sudo genprof /usr/bin/skype
    
    После этого будет создан профиль для  сбора информации о работе приложения. В
    другой консоли запускаем Skype, делаем тестовый вызов и выходим из Skype.
    
    Повторно запускаем:
    
       sudo genprof /usr/bin/skype
    
    и инициируем сканирование накопленных событий, выбрав "S". В процессе вывода
    результатов выбираем что можно процессу, а что нет. В завершении жмём "S" для
    сохранения профиля и "F" для выхода.
    
    Профиль будет создан в файле /etc/apparmor.d/usr.bin.skype
    Если нет желания разбираться с составлением правил вручную можно использовать готовый профиль:
    
       #include <tunables/global>
       /usr/bin/skype {
          #include <abstractions/audio>
          #include <abstractions/base>
          #include <abstractions/fonts>
          #include <abstractions/nameservice>
          #include <abstractions/nvidia>
          /etc/gai.conf r,
          /home/*/.ICEauthority r,
          /home/*/.Skype/** krw,
          /home/*/.Xauthority r,
          /home/*/.config/* kr,
          /home/*/.kde/share/config/kioslaverc r,
          /proc/*/cmdline r,
          /tmp/.ICE-unix/* w,
          /tmp/.X11-unix/* w,
          /usr/bin/skype mr,
          /usr/share/X11/* r,
          /usr/share/icons/** r,
          /usr/share/skype/** kr,
        }
    
    Перезапускаем AppArmor:
    
       sudo /etc/init.d/apparmor restart
    
    Активируем работу Skype в sandbox-окружении Apparmor:
    
       sudo aa-enforce skype
    
    Проверяем результат:
    
     sudo sudo apparmor_status
    
     
    ----* Решение проблемы резолвинга имен в php-fpm в chroot-режиме   Автор: gara  [комментарии]
     
    В php-fpm chroot возникает проблема - не резолвятся DNS имена. В частности не
    работает функция gethostbyname.
    
    Причина проблемы в том, что в режиме chroot, php-fpm не видит файлов
    
       etc/hosts  
       etc/resolv.conf
       lib64/libnss_dns.so.2
    
       (или lib/libnss_dns.so.2 если система 32-х битная)
    
    Простейшим выходом является создание жестких ссылок внутрь chroot-окружения.
    Символические ссылки работать не будут, как и жесткие ссылки при размещении
    chroot-области на другом дисковом разделе, в этом случае нужно просто
    скопировать нужные файлы в chroot.
    
       #!/bin/bash
    
       export CHROOT_FPM="/opt/www/domain"
    
       mkdir $CHROOT_FPM/etc
       mkdir $CHROOT_FPM/lib64
    
       ln  /etc/hosts          $CHROOT_FPM/etc/hosts;
       ln /etc/resolv.conf     $CHROOT_FPM/etc/resolv.conf
    
       #ln /etc/nsswitch.conf     $CHROOT_FPM/etc/nsswitch.conf
       cp /lib64/libnss_dns.so.2  $CHROOT_FPM/lib64/libnss_dns.so.2
    
    
    Имя библиотеки libnss_dns возможно придется подкоректировать.
    После копирования/создания ссылок на нужные файлы, нужно обязательно перезапустить php-fpm.
    
     
    ----* Использование контейнеров LXC в Debian/Ubuntu   Автор: Heretic  [комментарии]
     
    Контейнеры LXC позволяют изолировать процессы и ресурсы, работающие в рамках
    одной операционной системы, не прибегая к использованию виртуализации.
    Положительным аспектом LXC является использование единого пространства
    системных буферов, например, единый для базовой системы и всех контейнеров
    дисковый кэш. Наиболее близкими аналогами LXC являются Solaris Zones и FreeBSD jail.
    
    В качестве серверной операционной системы была использована Ubuntu 10.04 LTS, в
    качестве виртуальных машин использован Debian Lenny.
    
    Организация сетевого соединения для контейнера.
    
    Воспользуемся сетевым мостом для создания общего сегмента сети.
    Устанавливаем пакеты для создания моста:
    
       sudo aptitude install bridge-utils
    
    Настроим мост, для этого приведем файл /etc/network/interfaces к следующему виду:
    
       # The loopback network interface
       auto lo
       iface lo inet loopback
    
       # Комментируем активные до настройки сетевого моста опции
       #allow-hotplug eth0
       #iface eth0 inet dhcp
    
       # Setup bridge
       auto br0
       iface br0 inet dhcp
        bridge_ports eth0
        bridge_fd 0
    
    Как можно увидеть из файла /etc/network/interfaces, eth0 закомментирован и
    добавлен новый интерфейс br0.
    
    Далее перезапускаем сеть:
    
        sudo /etc/init.d/networking restart
    
    Если использует ручная настройка сети, то нужно сделать так:
    
       auto br0
       iface br0 inet static
        bridge_ports eth0
        bridge_fd 0
        address 192.168.82.25
        netmask 255.255.255.0
        gateway 192.168.82.1
        dns-nameservers 192.168.82.1
    
    Установка LXC, установка cgroups
    
    Установим lxc: 
    
       sudo aptitude install lxc
    
    Создадим директорию /cgroup и примонтируем cgroup (может быть где угодно):
    
       sudo mkdir /cgroup
    
    Добавляем следующие строки в /etc/fstab:
    
       cgroup        /cgroup        cgroup        defaults    0    0
    
    И монтируем cgroups:
    
       sudo mount cgroup
    
    До того как начать собирать контейнер, проверим окружение через lxc-checkconfig:
    
    
       lxc-checkconfig
    
       Kernel config /proc/config.gz not found, looking in other places...
       Found kernel config file /boot/config-2.6.32-3-686
       --- Namespaces ---
       Namespaces: enabled
       Utsname namespace: enabled
       ...
    
    Все параметры должны быть включены (для ubuntu 10.04, в Debian squeeze Cgroup
    memory controller: disabled ).
    
    Создание первого контейнера
    
    Мы будем использовать оригинальную версию скрипта lxc-debian, он находится в
    файле /usr/share/doc/lxc/examples/lxc-debian.gz.
    
    Скопируем файл /usr/share/doc/lxc/examples/lxc-debian.gz в /usr/local/sbin/
    распакуем его и поставим бит запуска:
    
       sudo cp /usr/share/doc/lxc/examples/lxc-debian.gz /usr/local/sbin/
       sudo gunzip /usr/local/sbin/lxc-debian.gz
       sudo chmod +x /usr/local/sbin/lxc-debian
    
    Перед запуском этого скрипта требуется установить debootstrap.
    
       sudo aptitude install debootstrap
    
    Теперь сделаем первую вирутальную машину. По умолчанию директория развертывания
    контейнеров находится в /var/lib/lxc/ , параметром -p можно указать
    произвольное расположение вируальной машины.
    
       sudo mkdir -p /lxc/vm0
       sudo lxc-debian -p /lxc/vm0
    
    Это может занять некоторое время. Скрипт так же настроит локаль. После
    окончания установки нужно настроить виртуальную машину.
    Идем в /lxc/vm0 и правим файл конфигурации (config):
    
       lxc.tty = 4
       lxc.pts = 1024
       lxc.rootfs = /srv/lxc/vm0/rootfs
       lxc.cgroup.devices.deny = a
       # /dev/null and zero
       lxc.cgroup.devices.allow = c 1:3 rwm
       lxc.cgroup.devices.allow = c 1:5 rwm
       # consoles
       lxc.cgroup.devices.allow = c 5:1 rwm
       lxc.cgroup.devices.allow = c 5:0 rwm
       lxc.cgroup.devices.allow = c 4:0 rwm
       lxc.cgroup.devices.allow = c 4:1 rwm
       # /dev/{,u}random
       lxc.cgroup.devices.allow = c 1:9 rwm
       lxc.cgroup.devices.allow = c 1:8 rwm
       lxc.cgroup.devices.allow = c 136:* rwm
       lxc.cgroup.devices.allow = c 5:2 rwm
       # rtc
       lxc.cgroup.devices.allow = c 254:0 rwm
    
       # <<<< Добавляем эти строки
       lxc.utsname = vm0
       lxc.network.type = veth
       lxc.network.flags = up
       lxc.network.link = br0
       # lxc.network.name = eth0
       # lxc.network.hwaddr = 00:FF:12:34:56:78
       lxc.network.ipv4 = 192.168.82.28/24
    
    
    Рассмотрим параметры поподробнее:
    
    lxc.utsname = vm0 Имя хоста виртуальной машины
    
    lxc.network.type = veth Тип сети с которой работаем (man lxc.conf), используем
    veth если работаем с мостом.
    
    lxc.network.flags = up Сообщаем что нужно поднимать сетевой интерфейс при запуске системы.
    
    lxc.network.link = br0 Мост через который будет работать вируальный интерфейс.
    
    lxc.network.name = eth0 Имя сетевого интерфейса в контейнере. Если не 
    устанавливать будет eth0, по умолчанию.
    
    lxc.network.hwaddr = 00:FF:12:34:56:78 Мак адрес устройства которое используется.
    
    lxc.network.ipv4 = 192.168.82.28/24 Сетевой адрес который будет присвоен виртуальному интерфейсу.
    
    Так же требуется отредактировать /etc/network/interfaces в контейнере (/lxc/vm0/rootfs/etc/network/interfaces)
    
    Создаем контейнер который связывает имя конрейнера с файлом настроек. Имя будет
    использовано для управления единичным контейнером.
    
       sudo lxc-create -n vm0 -f /lxc/vm0/config
    
    Запустим вируальную машину.
    
       sudo lxc-start -n vm0 -d
    
    Проверяем запущена ли она:
    
       sudo lxc-info -n vm0
    
       'vm0' is RUNNING
    
    Теперь можно подключиться к консоли контейнера используя lxc-console:
    
       sudo lxc-console -n vm0
    
    Вводим имя пользователя root и получаем вход в систему (без пароля).
    Устанавливаем пароль пользователю root:
    
       sudo passwd
    
    Добавляем не привилегированного пользователя.
    
       sudo adduser admin
    
    Хорошо наш контейнер работает, теперь остановим его делается это следующим образом:
    
       sudo lxc-stop -n vm0
    
    И проверяем его статус через lxc-info
    
       sudo lxc-info -n vm0
       'vm0' is STOPPED
    
    
    Еще один контейнер
    
    У нас есть контейнер vm0 с минимальной системой и установленными паролями рута
    и не привилегированного пользователя, из этого контейнера клонируем еще один.
    Для этого первая виртуальная машина должна быть остановлена. Создаем папку vm1
    в /lxc и копируем туда содержимое vm0
    
       cd /lxc
       sudo mkdir vm1
       sudo cp -Rv ./vm0/* ./vm1/
       cd ./vm1/
    
    Теперь нужно подправить файл конфигурации для vm1 (сеть, имя и т.д.)
    
    Ограничения
    
    
    При настройке Xen или KVM можно настроить количество памяти, количество
    виртуальных процессов, а так же настроить планировщик. Это же можно сделать с
    помощью cgroups в LXC. Прежде нужно запомнить что все настройки cgroup
    полностью динамические, т.е. вы можете их изменять в любое время, так что
    будьте осторожны.
    
    Все значения cgroup можно задать следующими способами:
    
       lxc-cgroup -n vm0 <cgroup-name> <value>
       echo <value> > /cgroup/vm0/<cgroup-name>
    
    в конфигурационном файле: "lxc.cgroup.<cgroup-name> = <value>"
    
    В примерах будем использовать настройку через конфигурационный файл.
    
    Для обозначения размера, например памяти, можно использовать K, M или G, например:
    
       echo "400M" > /cgroup/vm0/memory.limit_in_bytes
    
    Допустимые параметры. Для начала, мы можем посмотреть в каталог /cgroup/vm0
    (если vm0 не запущен - запустите сейчас). Мы можем увидеть следующее:
    
       ls -1 /cgroup/vm0/
    
       cgroup.procs
       cpuacct.stat
       cpuacct.usage
       cpuacct.usage_percpu
       cpuset.cpu_exclusive
       cpuset.cpus
       cpuset.mem_exclusive
       cpuset.mem_hardwall
       cpuset.memory_migrate
       cpuset.memory_pressure
       cpuset.memory_spread_page
       cpuset.memory_spread_slab
       cpuset.mems
       cpuset.sched_load_balance
       cpuset.sched_relax_domain_level
       cpu.shares
       devices.allow
       devices.deny
       devices.list
       freezer.state
       memory.failcnt
       memory.force_empty
       memory.limit_in_bytes
       memory.max_usage_in_bytes
       memory.memsw.failcnt
       memory.memsw.limit_in_bytes
       memory.memsw.max_usage_in_bytes
       memory.memsw.usage_in_bytes
       memory.soft_limit_in_bytes
       memory.stat
       memory.swappiness
       memory.usage_in_bytes
       memory.use_hierarchy
       net_cls.classid
       notify_on_release
       tasks
      
    Не будем вдаваться в описание каждого параметра, подробно можно посмотреть здесь.
    
    Ограничение памяти и файла подкачки
    
    Не снижайте количество памяти для запущенного контейнера, если вы не уверены что делаете.
    Максимальное количество памяти для виртуальной машины:
    
       lxc.cgroup.memory.limit_in_bytes = 256M
    
    Максимальное количество swap для виртуальной машины:
    
       lxc.cgroup.memory.memsw.limit_in_bytes = 1G
    
    Больше информации по работе с памятью можно найти  здесь.
    
    Ограничение CPU
    
    Есть два варианта ограничения CPU. Первый, можно ограничить через планировщик и
    второй - можно ограничить через cgroup.
    
    Планировщик 
    Планировщик работает следующим образом: Можно присвоить vm0 значение 10 и vm1
    значение 20. Это означает что каждую секунду процессорного времени vm1 получит
    двойное количество циклов процессора. По умолчанию значение установлено в 1024.
    
       lxc.cgroup.cpu.shares = 512
    
    Больше о планировщике CPU читаем здесь.
    
    Так же можно установить количество используемых процессоров в контейнере.
    Допустим у вас 4 CPU, то по умолчанию для всех является значение 0-3
    (использовать все процессоры).
    
    Использовать первый cpu:
    
       lxc.cgroup.cpuset.cpus = 0
    
    использовать первый, второй и последний cpu.
    
       lxc.cgroup.cpuset.cpus = 0-1,3
    
    использовать первый и последний cpu.
    
       lxc.cgroup.cpuset.cpus = 0,3
    
    Подробнее здесь.
    
    Ограничение жесткого диска
    
    Пока это нельзя сделать через cgroups, но можно сделать через LVM.
    
    
    Как безопасно остановить виртуальную машину
    
    lxc-stop просто убивает родительский процесс lxc-start, если  требуется
    безопасно выключить, то в настоящие время не существует другого решения, как
    остановить виртуальную машину через SSH или lxc-console:
    
       sudo lxc-console -n vm0
       #vm0> init 0
    
    Нужно подождать пока остановятся все процессы (за этим можно понаблюдать через
    pstree или htop) и затем останавливаем виртуальную машину.
    
       sudo lxc-stop -n vm0
    
    Как навсегда удалить виртуальную машину
    
    Останавливаем виртуальную машину и используем команду lxc-destroy
    
       sudo lxc-destroy -n vm0
    
    Она удалит все файлы из /lxc/vm0, так сказано в документации, но она не удалила
    файлы из каталога поэтому пришлось удалять самому.
    
    Как заморозить и "разморозить" контейнер
    
    LXC может заморозить все процессы в запущенном контейнере, тем самым LXC просто
    блокирует все процессы.
    
       sudo lxc-freeze -n vm0
    
    После запуска все будет записано в память (и swap).
    
    Использованные источники
    * http://www.ibm.com/developerworks/ru/library/l-lxc-containers/
    * https://help.ubuntu.com/community/LXC
    * http://blog.bodhizazen.net/linux/lxc-configure-ubuntu-lucid-containers/
    * http://blog.bodhizazen.net/linux/lxc-linux-containers/
    * http://lxc.teegra.net/#_setup_of_the_controlling_host
    * http://blog.foaa.de/2010/05/lxc-on-debian-squeeze/#pni-top0
    
     
    ----* Подготовка chroot-окружения в Debian или Ubuntu (доп. ссылка 1)   [комментарии]
     
    Для создания chroot-окружения в Debian или Ubuntu можно использовать пакет
    debootstrap, а для управления - schroot.
    
      apt-get install debootstrap
    
    Создадим минимальный chroot в Ubuntu:
    
      debootstrap --variant=buildd --arch i386 hardy /home/chroot_web http://archive.ubuntu.com/ubuntu/
    
    в Debian:
    
      debootstrap --arch i386 lenny /home/chroot_web http://ftp.us.debian.org/debian
    
    при этом в Ubuntu можно создавать chroot на базе Debian и наоборот.
    
    Для последующей установки пакетов из chroot копируем файлы конфигурации APT и резолвера:
    
      cp /etc/resolv.conf /home/chroot_web/etc/resolv.conf
      cp /etc/apt/sources.list /home/chroot_web/etc/apt/
    
    Заходим в chroot-окружение:
    
      sudo chroot /home/chroot_web
    
    Устанавливаем в нем apache:
    
     apt-get update
     apt-get install apache2
    
    Устанавливаем необходимые для работы и сборки пакетов составляющие:
    
      apt-get --no-install-recommends install wget debconf devscripts gnupg
      apt-get update
    
    Конфигурируем локаль:
    
      apt-get install locales dialog
      locale-gen ru_RU.UTF-8
      tzselect; TZ='Europe/Moscow';
    
    Пробрасываем в chroot системные псевдо ФС, в /etc/fstab основной системы добавляем:
    
       /proc /home/chroot_web/proc none rbind 0 0
       /dev /home/chroot_web/dev none rbind 0 0
       /sys /home/chroot_web/sys none rbind 0 0
    
    Запускаем сервис:
       chroot /home/chroot_web /etc/init.d/apache2 start
    
    Когда chroot-окружений много или внутри chroot запускается несколько сервисов
    для управления удобно использовать schroot
    
       apt-get install schroot
    
    Создаем /etc/schroot/schroot.conf:
    
       [hardy]
       description=Apache Chroot
       location=/home/chroot_web
       priority=3
       users=webuser
       groups=sbuild
       root-groups=root
    
    Запускаем все chroot-окружения и определенные в них сервисы:
    
       schroot --all -- su -c /etc/init.d/rc\ 2 -
    
     
    ----* Подготовка chroot-окружения в Red Hat-подобных Linux (доп. ссылка 1)   [комментарии]
     
    Формирование Chroot-окружения в CentOS, Fedora и RHEL.
    
    Создаем БД для пакетного менеджера RPM внутри создаваемого chroot:
       mkdir -p /home/chroot_web/var/lib/rpm
       rpm --root /home/chroot_web --initdb
    
    Загружаем базовые пакеты с описанием текущего релиза Fedora Linux (для CenOS
    пишем centos-release, для RHEL - redhat-release):
       yumdownloader --destdir=/var/tmp fedora-release
       cd /var/tmp
       rpm --root /home/chroot_web -ivh --nodeps fedora-release*rpm
    
    Ставим в chroot apache и все необходимые для его работы зависимости, в итоге
    получим минимальную систему для работы httpd:
    
      yum --installroot=/home/chroot_web -y install httpd
    
    После настройки Apache запускаем его:
    
      chroot /home/chroot_web /usr/sbin/apachectl start
    
     
    ----* Помещение OpenSSH пользователей в изолированное sftp окружение (доп. ссылка 1)   [комментарии]
     
    Начиная с релиза 4.9 в OpenSSH появилась возможность помещать отдельных
    пользователей в изолированное окружение.
    Помещение в chroot управляется через директиву ChrootDirectory, задаваемую в
    конфигурационном файле sshd_config.
    При задействовании sftp-server интегрированного в sshd, при этом не требуется
    формирование специального chroot окружения.
    
    Пример помещения в chroot:
    
       AllowUsers user1 user2 user3@192.168.1.1 user3@192.168.2.*
       Match user user2, user3
             ChrootDirectory /home/%u
             X11Forwarding no
             AllowTcpForwarding no
             ForceCommand internal-sftp
    
       Subsystem       sftp    internal-sftp
    
    Пользователь user1 имеет возможность входа в shell, в то время как user2 и
    user3 могут работать только по sftp,
    без возможность выхода за пределы своей домашней директории.
    При этом user3 может входить только с машины 192.168.1.1 и подсети 192.168.2.0/24.
    
    Опция "ForceCommand internal-sftp" разрешает пользователю использовать только
    sftp, встроенный в sshd.
    
    Директория, в которую происходит chroot пользователя (не имеет значения, ssh или sftp), 
    должна принадлежать пользователю root и права на запись должны принадлежать
    только владельцу (750, например).
    
    При необходимости пускать пользователей в shell, необходимо сформировать
    минимальное chroot-окружение,
    скопировав туда необходимые для работы программы и библиотеки.
    
    Например, создадим для пользователей, входящих в группу chrootusers, окружение /home/chroot
    
    В /etc/ssh/sshd_config добавим:
    
       Match Group chrootusers
           ChrootDirectory /home/chroot
           X11Forwarding no
           AllowTcpForwarding no
    
    Для формирования chroot можно использовать скрипт make_chroot_jail.sh,
    поддерживающий Debian, Suse, Fedora и Redhat Linux:
       http://www.fuschlberger.net/programs/ssh-scp-sftp-chroot-jail/
    
    Также можно порекомендовать скрипт sync_chroot.pl (ftp://ftp.opennet.ru/pub/security/chroot/ ), 
    который автоматически находит и копирует в chroot недостающие библиотеки для
    находящихся внутри chroot программ.
    
    Рассмотрим создание chroot в Debian или Ubuntu Linux.
    
    Установим необходимые для работы скрипта утилиты:
    
       apt-get install sudo debianutils coreutils
    
    Копируем скрипт make_chroot_jail.sh:
    
       wget http://www.fuschlberger.net/programs/ssh-scp-sftp-chroot-jail/make_chroot_jail.sh
       chmod 700 ./make_chroot_jail.sh
    
    Определяем список программ для chroot-окружения, в make_chroot_jail.sh находим
    строки и меняем на свое усмотрение:
    
       ...
       elif [ "$DISTRO" = DEBIAN ]; then
         APPS="/bin/bash /bin/cp /usr/bin/dircolors /bin/ls /bin/mkdir \
         /bin/mv /bin/rm /bin/rmdir /bin/sh /bin/su /usr/bin/groups \
         /usr/bin/id /usr/bin/rsync /usr/bin/ssh /usr/bin/scp \
         /sbin/unix_chkpwd /usr/bin/vi"
       else
       ...
    
    Формат вызова скрипта:
       make_chroot_jail.sh логин путь_к_shell путь_к_chroot
    
    Для создания окружения с shell по умолчанию bash для пользователя user1 выполним:
    
       ./make_chroot_jail.sh user1 /bin/bash /home/jail
    
    При этом скрипт автоматически скопирует все недостающие в chroot файлы и
    создаст директорию /home/jail/user1
    
    После обновления базовой системы, обновить chroot можно командой:
    
       ./make_chroot_jail.sh update /bin/bash /home/jail
    
     
    ----* Монтирование директории пользователя при его входе в Linux систему (доп. ссылка 1)   [комментарии]
     
    Имеем: неизменную базовую /home директорию.
    Хотим: отдельно держать изменения внесенные пользователями, чтобы они не влияли на базовую /home.
                изменения держать в рамдиске, так чтобы они не сохранялись при следующем входе
    Решение: 
      - unionfs - для отделения данных пользователя от read-only основы.
      - tmpfs - для создания /tmp директории с временными файлами, хранимой в ОЗУ.
      - pam-mount (http://pam-mount.sourceforge.net/) - PAM модуль для автоматического 
      монтирования разделов в момент входа пользователя в систему.
    
    Устанавливаем пакеты (пример для Debian  и Ubuntu):
       apt-get install unionfs-modules-`uname -r`
       apt-get install libpam-mount 
    
    Настраиваем pam_mount (/etc/security/pam_mount.conf)
    
       volume debiosk tmpfs - tmpfs /tmp/tmpfs "size=15M,uid=debiosk,gid=debiosk,mode=0700" - - 
       volume debiosk unionfs - unionfs /home/debiosk "dirs=/tmp/tmpfs:/home/debiosk=ro" - - 
    
    
    где
     "volume" - ключевое слово, сигнализирующее об описании раздела;
     "debiosk" - имя пользователя, для которого определены правила монтирования;
      "tmpfs" - тип файловой системы;
      " - " - сигнализирует о неиспользовании монтирования с удаленного сервера;
      "/tmp/tmpfs" - точка монтирования;
      "size=15M,uid=debiosk,gid=debiosk,mode=0700" - параметры монтирования tmpfs:
              "size=15m," - размер;
              "uid=debiosk,gid=debiosk,"  - владелец;
              "mode=0700" - права доступа;
       "dirs=/tmp/tmpfs:/home/debiosk=ro" - параметры монтирования unionfs: 
               указывают отобразить изменения /home/debiosk в директории /tmp/tmpfs
    
    
    Добавляем строку "@include common-pammount" в /etc/pam.d/login, /etc/pam.d/su и /etc/pam.d/xdm 
    
    Теперь пользователь debiosk каждый раз будет получать исходную домашнюю директорию,
    а изменения будут действовать только в пределах сессии.
    
     
    ----* Быстрое создание jail-машины во FreeBSD (доп. ссылка 1)   Автор: mr-tacitus  [комментарии]
     
    Нам понадобится первый установочный диск FreeBSD 6.2 и немного свободного времени. 
    Предполагается что наша jail-машина будет размещена в директории /var/jail.
    
    Список действий:
    
    1. Создать директорию /var/jail/machine для jail-машины;
    
    2. Смонтировать установочный диск и распаковать базовые файлы в директорию jail-машины:
    
       # mount /cdrom
    
    для bash:
    
       # DESTDIR=/var/jail/machine /cdrom/6.2-RELEASE/base/install.sh
    
    для csh:
    
       # env DESTDIR=/var/jail/machine /cdrom/6.2-RELEASE/base/install.sh
    
    3. Создать пустой файл /var/jail/machine/etc/fstab:
    
       # touch /var/jail/machine/etc/fstab
    
    4. Создать файл /var/jail/machine/etc/rc.conf со следующим содержанием:
    
       # Запускаем sshd
       sshd_enable="YES"
       sendmail_enable="NONE"
       syslogd_flags="-ss"
       rpcbind_enable="NO"
       network_interfaces=""
    
    5. Теперь требуется создать непривилегированного пользователя и    изменить
    пароль пользователя root.
    Входим в каталог jail-машины
    
       # chroot /var/jail/machine /bin/csh
    
    Создаем пользователя
    
       # adduser
    
    Меняем пароль пользователя root
    
       # passwd
       # exit
    
    6. В файл /etc/rc.conf основной системы добавить:
    
       # Разрешаем запуск jail-машин
       jail_enable="YES"
       # Запрещаем им менять свое имя jail_set_hostname_allow="NO"
       # Перечисляем jail-машины в системе.
       jail_list="machine"
    
       # Jail-машина "machine"
       # Корневая директория jail_machine_rootdir="/var/jail/machine"
       # Имя jail_machine_hostname="machine.local"
       # IP-адрес jail_machine_ip="192.168.0.10"
       # На какой сетевой интерфейс будет цепляться jail-машина  
       jail_machine_interface="ed0"
       # монтируем файловую систему devfs внутри jail-машины. 
       jail_machine_devfs_enable="YES"
       # Скрипты запуска и останова 
       jail_machine_exec_start="/bin/sh /etc/rc"
       jail_machine_exec_stop="/bin/sh /etc/rc.shutdown"
    
    7. Кроме того требуется все запускаемые сервисы основной системы привязать к его ip-адресам 
    (не должны слушаться порты на ip-адресах jail-машин).
    Например, в rc.conf:
    
       # Супер-сервер inetd
       inetd_enable="YES"
       # Слушает порт только на 192.168.0.1
       inetd_flags="-wW -a 192.168.0.1"
       # Syslogd
       syslogd_enable="YES"
       # Не слушать порты
       syslogd_flags="-ss"
    
    8. Запускаем созданную jail-машину:
    
       # /etc/rc.d/jail start
    
     
    ----* Создание 32-битного chroot окружения в 64-битной Debian установке (доп. ссылка 1)   Автор: Amadeu A. Barbosa Jr  [комментарии]
     
    Ниже пример организации 32-битного chroot окружения в 64-битной системе.
    
    Устанавливаем пакет schroot
       aptitude install schroot 
    
    Создаем файл конфигурации /etc/schroot/schroot.conf:
       [sid]
       description=Debian sid (unstable)
       location=/srv/chroot/sid
       priority=3
       users=YOUR_USER
       groups=SOME_GROUP_LIKE_users
       root-groups=YOUR_ADMIN_USER
    
    Формируем chroot окружение:
        debootstrap --arch i386 sid /srv/chroot/sid http://ftp.br.debian.org/debian 
    
    Установка программ в chroot:
        schroot -c sid -p aptitude install wengophone
    
    Монтируем /proc и /dev основной системы в chroot:
       mount /dev /srv/chroot/sid/dev -o bind
       mount /proc /srv/chroot/sid/proc -o bind
    
    Разрешаем запуск графических приложений из chroot на основном X сервере:
        xhost +
    
    Запускаем приложения wengophone и skype:
        schroot -c sid -p wengophone
        schroot -c sid -p skype
    
    Закрываем полный доступ к X серверу.
        xhost -
    
     
    ----* Как решить проблему с ведением логов у программ в chroot окружении   [комментарии]
     
    Например, в postfix запущенном в chroot, через настройки в master.cf, при перезапуске syslogd 
    перестают писаться логи qmgr, тем временем все остальные логи пишутся нормально.
    
    Решение - необходимо создать дополнительный log сокет в chroot окружении:
       FreeBSD: "syslogd -l /var/spool/postfix/dev/log"
       Linux: "syslogd -a /var/spool/postfix/dev/log"
    
     
    ----* Помещение пользователя в chroot при входе в систему (доп. ссылка 1)   Автор: HFSC  [комментарии]
     
    В качестве шелла пользователю назначается скрипт /bin/chrsh
    echo "/bin/chrsh" >> /etc/shells
    cat >> /bin/chrsh << EOF
    #!/bin/sh
    /usr/bin/sudo /usr/bin/chroot /home/$USER /bin/bash
    EOF 
    chsh -s /bin/chrsh логин
    
     
    ----* Как автоматизировать перемещение нужных библиотек в chroot окружение  (доп. ссылка 1)   [комментарии]
     
    ldd /usr/local/libexec/apache/* | grep '=>' | awk {' print $3 '} | \
         grep '/usr/lib' | xargs -J % install -C % chroot_dir/usr/lib/
    ldd /usr/local/libexec/apache/* | grep '=>' | awk {' print $3 '} | \
         grep '/usr/local/lib' | xargs -J % install -C % chroot_dir/usr/local/lib/
    ldd /usr/local/libexec/apache/* | grep '=>' | awk {' print $3 '} | \
         grep '/usr/X11R6/lib' | xargs -J % install -C % chroot_dir/usr/X11R6/lib/
    
    Пару скриптов для синхронизации файлов в chroot - ftp://ftp.opennet.ru/pub/security/chroot/
    
     
    ----* Как посмотреть какие файлы пытается открыть или выполнить программа   [комментарии]
     
    strace -f -o strace.txt -e execve программа
    strace -f -o strace.txt -e open,ioctl программа
    
     
    ----* Почему suexec может не работать при запуске Apache в режиме chroot. (доп. ссылка 1)   [обсудить]
     
    1. В chroot окружении обязательно должен быть /etc/passwd с пользователями для
    которых используется suexec.
    2. Помещена ли в bin директорию программа suexec ?
    3. Установлен ли suid root флаг для программы suexec ? (при копировании suid флаг исчезает).
    4. Все ли динамические библиотеки присутствуют:
       chroot /hst /usr/local/apache/bin/ldd /usr/local/apache/bin/httpd
       chroot /hst /usr/local/apache/bin/ldd /usr/local/apache/bin/suexec
        предварительно положив ldd в /hst/usr/local/apache/bin/
    
     
    ----* Как узнать какие динамические библиотеки прилинкованы к программе   [комментарии]
     
    ldd файл
    
     

       Шифрование, PGP

    ----* Защита от подмены серверных TLS-сертификатов в результате MITM-атаки провайдером (доп. ссылка 1) (доп. ссылка 2)   [комментарии]
     
    Для предотвращения получения TLS-сертификатов третьими лицами, которые в ходе
    MITM-атаки могут контролировать трафик сервера, рекомендовано использовать
    DNS-запись CAA, через которую можно указать какой именно удостоверяющий центр и
    какая именно учётная запись в этом удостоверяющем центре авторизированы на
    выдачу сертификата для домена.
    
    CAA поддерживается в Let's Encrypt и не позволяет запросить сертификат,
    используя другой ACME-ключ. Для включения привязки в DNS-зону следует добавить:
    
    для привязки домена example.com к удостоверяющему центру letsencrypt.org:
    
       example.com. IN CAA 0 issue "letsencrypt.org"
    
    для дополнительно привязки к учётной записи acme-v02.api.letsencrypt.org/acme/acct/1234567890
    
       example.com. IN CAA 0 issue "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/1234567890"
    
    DNS-сервер должен быть размещён на отдельном сервере, не подверженном
    MITM-атаке. Для дополнительной защиты от подмены DNS необходимо использовать
    протокол DNSSEC, который помешает атакующим подменить  DNS-ответы с записью CAA.
    
    Дополнительно рекомендовано через Tor или внешние хосты наладить автоматический
    мониторинг  отсутствия подмены сертификатов, и подключиться к сервисам
    мониторинга CT-логов (Certificate Transparency, отражают выданные
    удостоверяющими центрами сертификаты) или вручную отслеживать появление
    незапрошенных сертификатов в CT-логах (https://crt.sh/). Также  рекомендовано
    выбирать размещённых в разных странах операторов хостинга, регистрации домена,
    DNS и удостоверяющих центров.
    
     
    ----* Перевод шифрованного раздела на LUKS2 и более надёжную функцию формирования ключа (доп. ссылка 1)   [комментарии]
     
    В шифрованных разделах LUKS1 в качестве функции формирования ключа (KDF, Key
    Derivation Function) на основе заданного пользователем пароля применяется
    функция PBKDF2, не обеспечивающая должную стойкость от подбора с использованием
    GPU. В LUKS2 в качестве KDF появилась возможность использования гибридной хэш-функции
    argon2id, которая помимо потребления
    вычислительных ресурсов, затрудняет распараллеливание и требует значительного
    объёма памяти.
    
    Например, подбор KDF-функции PBKDF2, рассчитанной на потребление CPU,  может
    эффективно распараллеливаться на GPU Geforce 4090 c 16384 вычислительными
    блоками, но в случае применения argon2id подбор упирается в размер видеопамяти
    (при потреблении 1 ГБ на каждую операцию подбора, на GPU с 24 ГБ памяти можно
    обеспечить лишь подбор в 24 параллельных потока).
    
    Переключение с LUKS1 на LUKS2 с  argon2id.
    
    Определяем на каком устройстве находится шифрованный раздел:
    
       lsblk
    
       ...
       └─nvme0n1p3    259:3    0 474,8G  0 part  
         └─nvme0n1p3_crypt
                      253:0    0 474,8G  0 crypt 
           ├─vgubuntu--mate-root
           │          253:1    0 473,8G  0 lvm   /var/snap/firefox/common/host-hunspell
           │                                     /
           └─vgubuntu--mate-swap_1
                      253:2    0   980M  0 lvm   [SWAP]
    
    Сохраняем резервную копию заголовка LUKS и затем копируем на внешний носитель,
    чтобы иметь возможность восстановить состояние.
    
       sudo cryptsetup luksHeaderBackup /dev/nvme0n1p3 --header-backup-file /tmp/luksheader
    
    
    Проверяем версию LUKS:
    
       sudo cryptsetup luksDump /dev/nvme0n1p3
    
       ...
       Version:    1
       ...
       PBKDF:      pbkdf2
    
    Если версия 1, то необходимо обновить заголовок до LUKS2.
    
       sudo cryptsetup convert /dev/nvme0n1p3 --type luks2
    
    Проверяем, что с новым заголовком система по-прежнему грузится и если возникли
    проблемы восстанавливаем старый заголовок командой
    
       sudo cryptsetup luksHeaderRestore /dev/nvme0n1p3 --header-backup-file путь_к_скопированному_luksheader
    
    Ещё раз выполняем cryptsetup luksDump и проверяем алгоритм в секции Keyslots,
    если указано "pbkdf2" или "argon2i" следует обновить его до
    "argon2id":
    
       sudo cryptsetup luksConvertKey /dev/nvme0n1p3 --pbkdf argon2id
    
    Проверяем результат:
    
       sudo cryptsetup luksDump /dev/nvme0n1p3
    
       ...
       Version:       	2
       ...
       Keyslots:
         0: luks2
            ...
            PBKDF:      argon2id
            ...
    
        0: luks2
            ...
            PBKDF:      argon2id
            ...
    
     
    ----* Шифрование данных на существующем разделе ext4 без его переформатирования (доп. ссылка 1) (доп. ссылка 2)   [комментарии]
     
    Можно отметить два основных способа организации шифрования данных в уже
    существующей файловой системе Ext4, не требующие пересоздания раздела с
    переносом данных из резервной копии. Первый способ заключается в использовании
    встроенных в Ext4 возможностей по шифрованию отдельных каталогов, а второй в
    использовании команды "cryptsetup reencrypt" для прозрачного переноса ФС на
    новый шифрованный раздел LUKS. В любом случае создание полной резервной копии
    перед выполнением предложенных манипуляций обязательно.
    
    Первый способ наиболее простой и безопасный, но он ограничен использованием
    отдельных шифрованных каталогов, в которые можно перенести конфиденциальные
    данные, требующие защиты. Шифрование в Ext4 поддерживается при использовании
    как минимум ядра Linux 4.1 и утилит 2fsprogs 1.43.
    
    Выставляем в суперблоке раздела  c ФС ext4 флаг поддержки шифрования (в нашем случае /dev/sda1):
    
        sudo tune2fs -O encrypt /dev/sda1
    
    Создаём каталог, в котором будут храниться зашифрованные данные текущего пользователя:
    
        mkdir -p /secret/home/user
      
    Генерируем случайную salt-последовательность для последующего шифрования и
    сохраняем её в отдельный файл:
    
        echo 0x`head -c 16 /dev/urandom | xxd -p` > /home/user/.crypt_salt
     
    
    Создаём на базе данной salt-последовательности ключ для шифрования, указав для него пароль:
    
        e4crypt add_key -S /home/user/.crypt_salt
    
        Enter passphrase (echo disabled):
        Added key with descriptor [f467134ca2c48c33]
    
    Проверяем добавление ключа командой "keyctl show", которая поставляется в пакете keyutils.
    
      
    Активируем шифрование для каталога /secret/home/user, указав выданный идентификатор ключа:
    
        e4crypt set_policy f467134ca2c48c33 /secret/home/user
    
    Если после перезагрузки попытаться обратится к каталогу /secret/home/user без
    добавления ключа командой "e4crypt add_key", его содержимое будет показано в
    зашифрованном виде. Для расшифровки каталога при каждой загрузке необходимо
    настроить повторный вызов команды add_key для привязки ключа.
       
       e4crypt add_key -S /home/user/.crypt_salt
    
       Enter passphrase (echo disabled):
       Added key with descriptor [f467134ca2c48c33]
    
    Для просмотра привязанного к каталогу ключа можно использовать команду
    
       e4crypt get_policy /secret/home/user
    
    
    
    В случае необходимости шифрования всего содержимого можно использовать LUKS
    cryptsetup для шифрования имеющегося раздела без потери данных.
    
    Отмонтируем шифруемый раздел (при изменении корневого раздела нужно загрузиться
    с отдельного live-дистрибутива), проверяем целостность ФС и уменьшаем размер ФС
    для того, чтобы разместить заголвки LUKS на диске (в ФС должно быть достаточно
    свободного места):
    
       e2fsck -f /dev/sda4
       resize2fs /dev/sda4 размер_меньше_текущего_на_32МБ
    
    Шифруем содержимое имеющегося раздела без потери информации:
       
       cryptsetup reencrypt --encrypt /dev/sda4 --reduce-device-size 32M
       
    Открываем раздел:
    
       cryptsetup open /dev/sdXY home
      
    Увеличиваем размер ФС до свободной границы
    
       resize2fs /dev/mapper/home
    
    Монтируем раздел:
       
        mount /dev/mapper/home /mnt/home
    
    Смотрим UUID:
    
       blkid /dev/mapper/home 
    
    Добавляем информацию о разделе в /etc/crypttab
    
       home UUID=UUID_устройства_LUKS none
    
     
    ----* Создание шифрованных образов виртуальных машин (доп. ссылка 1) (доп. ссылка 2)   [комментарии]
     
    Инструкция по созданию полностью зашифрованного образа гостевой системы, в
    котором шифрование охватывает корневой раздел и стадию загрузки.
    
    Извлекаем содержимое корневого раздела образа виртуальной машины, который
    требуется зашифровать,  в tar-архив vm_root.tar. Проверяем, чтобы в образе были
    необходимые для шифрования и EFI-загрузки разделов утилиты, такие как
    cryptodisk и grub-efi.
    
    Создаём файл с дисковым образом, содержащим два раздела - небольшой раздел для
    EFI (p1, 100МБ)  и корневой раздел, содержимое которого будет зашифровано (p2).
    
    
       truncate -s 4GB disk.img
       parted disk.img mklabel gpt
       parted disk.img mkpart primary 1Mib 100Mib
       parted disk.img mkpart primary 100Mib 100%
       parted disk.img set 1 esp on
       parted disk.img set 1 boot on
    
    Настраиваем EFI на первом разделе и дисковое шифрование LUKS на втором. Для
    повышения защищённости можно заполнить шифрованный раздел случайными числами,
    но это приведёт к увеличению размера итогового образа qcow2. Создаём на
    шифрованном разделе ФС Ext4.
    
    привязываем образ к loop-устройству
    
       losetup -P -f disk.img          
    
    определяем имя созданного устройства (/dev/loopN), в дальнейшем используем
    переменную $l вместо устройства
    
       l=($(losetup -l|grep disk.img)) 
    
    создаём раздел с EFI, используем VFAT
    
       mkfs.vfat ${l}p1
    
    определяем UUID раздела EFI
    
       blkid ${l}p1  
    
    создаём шифрованный раздел, в процессе задаём временный пароль для расшифровки
    
       cryptsetup --type luks1 luksFormat ${l}p2 
    
    определяем UUID шифрованного раздела
    
       blkid ${l}p2 
    
    активируем шифрованный раздел и создаём на нём ФС ext4
    
       cryptsetup luksOpen ${l}p2 cr_root
       mkfs.ext4 /dev/mapper/cr_root
    
    монтируем раздел, копируем в него содержимое tar-архива с начинкой корневого
    раздела и создаём каталоги для точек монтирования /run, /sys, /proc и /dev.
    
       mount /dev/mapper/cr_root /mnt
       tar -C /mnt -xpf vm_root.tar
       for m in run sys proc dev; do mount --bind /$m /mnt/$m; done
    
    входим в окружение созданного корневого раздела
    
       chroot /mnt
    
    В /etc/fstab определяем метку корневого раздела (/dev/disk/cr_root) и раздела  EFI (/boot/efi).
    
    Настраиваем и устанавливаем загрузчик GRUB (в некоторых дистрибутивах вместо
    /boot/grub используется /boot/grub2, а вместо префикса "grub" - "grub2-"):
    
      echo "GRUB_ENABLE_CRYPTODISK=y" >> /etc/default/grub
       mount /boot/efi
       grub-install --removable --target=x86_64-efi
       grub-mkconfig -o /boot/grub/grub.cfg
    
    Для систем с mkinitramfs (Debian) дополнительно нужно добавить параметры
    шифрованного раздела в /etc/crypttab:
    
       cr_root UUID=<uuid> luks none
    
    После чего пересоздаём образ ram-диска с компонентами для начальной загрузки. 
    
    
    Для систем с dracut требуется изменить настройки /etc/default/grub, указав в
    GRUB_CMDLINE_LINUX привязку rd.luks.uuid=<UUID>. Для дистрибутивов с SELinux
    также нужно обновить метки (relabel).
    
    Отмонтируем созданные в процессе подготовки образа разделы из /mnt и пытаемся
    загрузить образ, используя режим EFI. В процессе загрузки вводим заданный ранее
    временный пароль и проверяем работоспособность окружения.
    
    Заменяем временный пароль на ключ для быстрой загрузки и настраиваем ram-диск
    для его использования. Для образа, примонтированного через /dev/sda:
    
       dd if=/dev/urandom bs=1 count=33|base64 -w 0 > /etc/cryptsetup-keys.d/luks-<UUID>.key
       chmod 600 /etc/cryptsetup-keys.d/luks-<UUID>.key
       cryptsetup --key-slot 1 luksAddKey /dev/sda2 # первичный ключ для восстановления
       cryptsetup --key-slot 0 luksRemoveKey /dev/sda2 # удаляем временный ключ
       cryptsetup --key-slot 0 --iter-time 1 luksAddKey /dev/sda2 /etc/cryptsetup-keys.d/luks-<UUID>.key
    
    Указание опции "-w 0" в dd необходимо для того, чтобы исключить появление в
    пароле символа перевода строки.
    
    Для систем с mkinitramfs теперь нужно изменить настройки /etc/crypttab, указав
    путь к сгенерированному ключу:
    
       cr_root UUID=<UUID> /etc/cryptsetup-keys.d/luks-<UUID>.key luks
    
    Для систем с dracut необходимо добавить hook ключа в /etc/dracut.conf.d, а для
    Debian также потребуется указать маску определения файла с ключом:
    
    cryptodisk.conf 
       install_items+=" /etc/cryptsetup-keys.d/* "
    
       echo "KEYFILE_PATTERN=\"/etc/cryptsetup-keys.d/*\"" >>/etc/cryptsetup-initramfs/conf-hook
    
    Теперь можно перегенерировать образ RAM-диска начальной загрузки. После попытки
    загрузки пароль будет спрошен один раз только на стадии запуска GRUB и на
    последующих стадиях загрузки запрашиваться не будет.
    
     
    ----* Включение ESNI и DNS over HTTPS в Firefox (доп. ссылка 1)   [комментарии]
     
    Включения network.security.esni.enabled=true в about:config недостаточно для
    активации в Firefox  TLS-расширения ESNI (Encrypted Server Name Indication),
    обеспечивающего шифрование данных о хосте, запрашиваемом в рамках HTTPS-соединения.
    
    На данным момент ESNI не работает без использования встроенного в Firefox
    резолвера "DNS over HTTPS" (network.trr.mode = 2). Использовать ESNI
    пока можно только при активации "DNS over HTTPS".
    
    
    Для включения "DNS over HTTPS" в about:config следует изменить значение
    переменной network.trr.mode. Значение 0 полностью отключает DoH;
    1 - используется DNS или DoH, в зависимости от того, что быстрее; 
    2 - используется DoH по умолчанию, а DNS как запасной вариант; 
    3 - используется только DoH; 
    4 - режим зеркалирования при котором DoH и DNS задействованы параллельно. 
    
    По умолчанию используется DNS-сервер CloudFlare, но его можно изменить через
    параметр network.trr.uri, например, можно установить:
    
    * https://dns.google.com/experimental 
    * https://cloudflare-dns.com/dns-query 
    * https://dns.quad9.net/dns-query (он же https://9.9.9.9/dns-query)
    * https://doh.powerdns.org
    * https://doh.cleanbrowsing.org/doh/family-filter/ (с родительским контролем)
    * https://doh2.dnswarden.com (с родительским контролем)
    * https://dns.dnsoverhttps.net/dns-query (проброс запросов через tor)
    * https://doh.securedns.eu/dns-query (заявлено об отсутствии ведения логов)
    * https://doh.crypto.sx/dns-query (на базе doh-proxy)
    * https://doh-de.blahdns.com/dns-query (используется реализация на Go)
    * https://dns.dns-over-https.com/dns-query (используется реализация на Go)
    * https://commons.host (реализация на Node.js)
    
     
    ----* Использование SystemTap для расшифровки локального HTTPS-трафика  (доп. ссылка 1)   [комментарии]
     
    В состав выпуска системы динамической трассировки SystemTap 3.3 добавлен
    скрипт capture_ssl_master_secrets.stp с  примером захвата сессионных ключей
    SSL/TLS  от приложений, использующих gnutls (libgnutls.so) или openssl
    (libssl.so), которые могут использоваться для организации расшифровки
    перехваченного трафика.
    
    Пример использования в Debian 9:
    
    Включаем SystemTap:
    
       sudo stap-prep
    
    Устанавливаем отладочные версии библиотек:
    
       sudo apt-get install libgnutls30-dbgsym libssl1.0.2-dbgsym libssl1.1-dbgsym libssl-dev
    
    Запускаем перехват ключей, генерируемых при вызове обработчиков
    tls1_generate_master_secret и generate_normal_master в libssl.so и libgnutls.so:
    
       ./capture_ssl_master_secrets.stp | tee keylog.txt &
    
    Включаем запись дампа трафика в формате pcap:
    
       sudo tcpdump -s0 -w traffic.pcap -U port 443 &
    
    Формируем тестовые запросы к защищённым сайтам:
    
       curl https://www.ssllabs.com/curl_secret
       wget https://www.ssllabs.com/wget_secret
       echo "GET /sclient_secret HTTP/1.1\nHost: www.ssllabs.com\n\n" | openssl s_client -connect www.ssllabs.com:443 -servername www.ssllabs.com
    
    Смотрим, какие ключи удалось захватить:
       cat keylog.txt
    
       # 1509378583063892 process("/usr/lib/x86_64-linux-gnu/libssl.so.1.0.2").function("tls1_generate_master_secret@./ssl/t1_enc.c:1134").return curl (24745)
       CLIENT_RANDOM 92...69000
       # 1509378587558501 process("/usr/lib/x86_64-linux-gnu/libgnutls.so.30.13.1").function("generate_normal_master@./lib/kx.c:131").return wget (24755)
       CLIENT_RANDOM 59f...28a 560...67c8
       # 1509378592611222 process("/usr/lib/x86_64-linux-gnu/libssl.so.1.1").function("tls1_generate_master_secret@../ssl/t1_enc.c:463").return openssl (24757)
       CLIENT_RANDOM aa2...fc93 741...127a
    
    Расшифровываем дамп трафика, используя захваченные ключи:
    
       $ tshark -o ssl.keylog_file:keylog.txt -d tcp.port==443,ssl -x -r traffic.pcap -V | grep -A1 'Decrypted SSL data' |grep "GET "
    
       0000  47 45 54 20 2f 63 75 72 6c 5f 73 65 63 72 65 74   GET /curl_secret
       0000  47 45 54 20 2f 77 67 65 74 5f 73 65 63 72 65 74   GET /wget_secret
       0000  47 45 54 20 2f 73 63 6c 69 65 6e 74 5f 73 65 63   GET /sclient_sec
    
     
    ----* Использование USB-брелоков Yubikey для ключей GPG и SSH (доп. ссылка 1)   [комментарии]
     
    Пример, как можно использовать USB-брелок Yubikey в качестве смарткарты для
    хранения GPG-ключей и ключей для аутентификации на SSH-серверах.
    
    Использование с GPG.
    
    Подключаем Yubikey к порту USB и проверяем, что он определился:
    
       gpg --card-status
       ...
       Version ..........: 2.1
       Manufacturer .....: Yubico
    
    Для переноса GPG-ключа на брелок запускаем "gpg --edit-key идентификатор_ключа"
    и выполняем в редакторе команду "keytocard" (внимание, закрытый ключ будет не
    скопирован, а перенесён, т.е. удалён с локальной машины, поэтому нужно заранее
    позаботиться о создании резервной копии).
    
    Убедимся, что ключ переместился:
    
       gpg --card-status | grep key
    
       URL of public key : [...]
       Signature key ....: [...] XXXX YYYY
       Encryption key....: [...] ZZZZ VVVV
       Authentication key: [...] AAAA BBBB
       General key info..: sub  rsa4096/QQQQQQ <foobar@domain.tld>
    
    Для проверки создадим шифрованное сообщение и расшифруем его:
    
       gpg --encrypt  --output /tmp/message.txt.enc -r foobar@domain.tld /tmp/message.txt
       gpg --decrypt /tmp/message.txt.enc
    
    
    Настраиваем SSH-ключи.
    
    Удостоверимся, что ключ аутентификации перенесён на Yubikey ("Authentication
    key" в выводе "gpg --card-status") и выполним экспорт открытого ключа SSH из Yubikey:
    
       gpg --export-ssh-key 0xAAAABBBB
      
    Далее, скопируем экспортированный ключ на SSH-сервер и настроим gpg-agent для
    работы в роли агента SSH:
    
       echo 'enable-ssh-support' >> ~/.gnupg/gpg-agent.conf       
    
    Перезапустим агенты GPG/SSH:
    
       killall gpg-agent
       killall ssh-agent
       gpg-agent --daemon
    
    Поменяем путь к сокету SSH_AUTH_SOCK на GPG. В ~/.bashrc:
    
       export SSH_AGENT_PID=""
       export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
    
    Проверим, виден ли ключ SSH при подключении брелока:
    
       ssh-add -l
    
       4096 SHA256:XXXX cardno:0006064XXXX (RSA)
    
    Всё в порядке, теперь при подключении к серверу SSH будет использовать ключ с брелока Yubikey.
    
     
    ----* Использование CAA записей в DNS для защиты от генерации фиктивных HTTPS-сертификатов   [комментарии]
     
    Начиная с сентября 2017 года удостоверяющим центрам предписано обязательно
    проверять CAA-записи в DNS перед генерацией сертификата. CAA (RFC-6844,
    Certificate Authority Authorization) позволяет владельцу домена явно определить
    удостоверяющий центр, который имеет полномочия для генерации сертификатов для
    указанного домена. При наличии CAA-записи все остальные удостоверяющие центры
    обязаны блокировать выдачу сертификатов от своего имени для данного домена и
    информировать его владельца о попытках компрометации.
    
    Например, добавление в зону домена example.com записей (для BIND 9.9.6 и более новых выпусков):
    
       $ORIGIN example.com
       .       CAA 0 issue "letsencrypt.org"
       .       CAA 0 iodef "mailto:security@example.com"
    или
       .       CAA 0 iodef "http://iodef.example.com/"
    
    
    указывает на то, что сертификаты для example.com  генерируются только
    удостоверяющим центром  Let's Encrypt (осуществляется проверка владельца
    домена "letsencrypt.org"). В поле iodef задаётся метод оповещения о попытке
    генерации сертификата. Поддерживается отправка уведомления на email или
    информирование через запрос к web-сервису (RFC-6546).
    
    При желании можно уточнить учётную запись под которой разрешено генерировать сертификаты:
    
       .       CAA 0 issue "letsencrypt.org; account=12345"
    
    Кроме  issue также поддерживается поле issuewild, через которое задаются
    дополнительные ограничения выдачи сертификатов с маской, охватывающей группу хостов.
    
    Допустимо указание нескольких записей issue, при использовании сертификатов от
    нескольких удостоверяющих центров:
    
      example.com.       CAA 0 issue "symantec.com"
      example.com.       CAA 0 issue "pki.goog"
      example.com.       CAA 0 issue "digicert.com"
    
    Проверить корректность создания записей CAA можно командой:
    
       dig +short +noshort example.com CAA
    
    Также доступен web-интерфейс для автоматической генерации конфигураций.
    
     
    ----* Методы обнаружения ключей OpenPGP   Автор: stargrave  [комментарии]
     
    Мы знаем email адрес человека и хотим с ним безопасно связаться. Как узнать его
    публичный OpenPGP ключ?
    
    Заранее обменяться ключами
    
       gpg --import MYKEYID.asc
    
    Самый простой, самый надёжный вариант. Но не всегда практичный и удобный, так
    как физическая встреча людей далеко не всегда возможна. Узнать или получить можно
    не весь ключ (он относительно больших размеров), но хотя бы
    отпечаток ключа, чтобы его можно было аутентифицировать, получив из сторонних источников.
    
    Экспорт ключа для записи его на бумагу, флешку, любой носитель:
    
       gpg --armor --output MYKEYID.asc --export MYKEYID
    
    Получить ключ через один из множества ключевых серверов (keyserver)
    
       gpg --keyserver KEYSERVER --recv-keys SOME@BODY.COM
    
    Технически, сервер ключей представляет собой что-то вроде публичного
    FTP-сервера, который умеет импортировать/обрабатывать OpenPGP записи и
    производить по ним поиск, работает по OpenPGP HTTP Keyserver Protocol (HKP)
    протоколу. Многие из них синхронизируются между собой автоматически и, загрузив
    ключ на один из них, можно ожидать его появление на других серверах, но это
    происходит далеко не всегда.
    
    Проблема заключается в том, что никто не обязывает загружать свои ключи на сервера:
    многие просто не хотят "светить" своей приватной информацией (email адрес, имя
    связанное с ним). Плюс заранее неизвестно, какой ключевой сервер надо использовать.
    
    Ключевые сервера только импортируют информацию, добавляют, но никогда не
    удаляют. С одной стороны, это хорошо, с другой, становится невозможно удалить
    ключ или часть его информации (UID-ы, подключи).
    
    Поддержка ключевых серверов имеется во множестве OpenPGP клиентов. Отправить
    ключ на сервер можно так:
    
       gpg --keyserver KEYSERVER_URL --send-keys MYKEYID
    
    Получить ключ через DNS-based Authentication of Named Entities (DANE)
    
       gpg --auto-key-locate dane --locate-key SOME@BODY.COM
    
    В этом варианте OpenPGP ключ полностью размещается внутри одной DNS записи
    hash(SOME)._openpgpkey.body.com. Из-за хэширования не утекает настоящее имя "SOME".
    
    DANE требует возможность управления DNS записями и накладывает ограничения на
    сервер (TCP и EDNS расширения обязательны почти наверняка). Многие пользователи
    приобретают собственные домены, хотя DNS, почтовые и Web-сервера располагаются
    у сторонних лиц. Например, можно использовать собственное доменное имя, но
    почтовые сервера Google, при этом пользуясь DANE без сторонних ключевых
    серверов и потерь приватности.
    
    DANE поддерживается клиентами не так широко, но его записи можно получить
    самостоятельно drill/dig запросами и импортировать результат в OpenPGP программу.
    
    Генерирование DANE CERT записи, которую можно вставить в зону DNS, делается просто:
    
       gpg --export --export-options export-dane MYKEYID
    
    Получить ключ через Web Key Discovery (WKD)
    
       gpg --auto-key-locate wkd --locate-key SOME@BODY.COM
    
    WKD протокол пока ещё на стадии утверждения и что-то может поменяться, но его
    реализация уже имеется в последних версиях GnuPG. Для получения ключа он
    использует HTTPS инфраструктуру. В данном примере команда приведёт к простому
    скачиванию бинарного (не Base64) ключа https://body.com/.well-known/openpgp/hu/hash(SOME).
    
    WKD использует HTTPS и может быть более удобен для использования и публикации
    ключей по сравнению с DNS. В нём нет задержек от кэша DNS, статические файлы
    проще обновлять чем DNS записи, особенно если это хочется сделать как-то
    автоматизировано на всём домене для множества пользователей. Однако, это ещё
    одна инфраструктура (кроме DNS), и обязательно работающая по TLS. Получение TLS
    сертификатов может являться проблемой.
    
    WKD поддерживается пока реже, чем DANE, но получить ключ с HTTPS
    сервера можно любым HTTP клиентом и сразу же импортировать в OpenPGP программу.
    
    Узнать хэш-часть до доменного имени, под которой необходимо загрузить ключ на
    HTTPS сервер, можно так:
    
       gpg --list-keys --with-wkd-hash MYKEYID
    
    Получить ключ через LDAP
    
       gpg --auto-key-locate ldap --locate-key SOME@BODY.COM
    
    В этом варианте будет обращение к LDAP серверу ldap://keys.body.com/ и поиск
    OpenPGP ключа на нём для заданного пользователя. Скорее всего, это имеет смысл
    для корпоративных решений, где LDAP применяется чаще, чем в масштабах Интернета.
    
    Но у нас пока нет доверия к полученным по HKP (ключевой сервер)/DANE/WKD
    ключам. Злоумышленник может иметь контроль над ними, может сделать MitM
    (дословно, "человек посредине")
    атаку. Как проверить целостность и аутентичность полученного ключа?
    
    Сравнить отпечаток с тем, что вы получили напрямую от человека
    
    Разместить отпечаток на визитке -- плёвое дело. Самый надёжный и простой
    вариант, но опять же, не всегда возможен физический контакт людей.
    
    Узнать отпечаток импортированного ключа можно так:
    
       gpg --list-keys --with-fingerprint MYKEYID
    
    Узнать отпечаток у владельца по сторонним каналам связи
    
    Использовать голосовую и/или видео связь, разные средства коммуникации (IRC,
    XMPP, PSYC, итд), телефонную связь, обычную почту с принимающей стороной.
    Компрометация всего и сразу маловероятна, но часто бывает, что ничего кроме
    собственно самой почты вы не знаете и не имеете никакой информации для аутентификации.
    
    Сравнить отпечаток с полученным по PKA
    
       gpg --auto-key-locate pka --locate-key SOME@BODY.COM
    
    PKA это DNS запись, но в отличиие от DANE, там размещён только отпечаток ключа,
    поэтому её можно переслать UDP пакетами, не предъявляя особых требований к DNS серверу.
    
    Генерирование PKA записи, которую можно вставить в зону DNS, делается просто:
    
       gpg --export --export-options export-pka MYKEYID
    
    Желательно использовать DNSSEC и TLS
    
    Записи DANE и PKA желательно аутентифицировать через DNSSEC. Это не даёт
    гарантий, что MitM-атака невозможна, но усложняет её. К примеру, WKD работает
    только поверх TLS.
    
    Использовать HKP, PKA, DANE, WKD по разным каналам связи
    
    Используйте разные DNS сервера, разные прокси, разные сети. Компрометация
    множества сетей и серверов - более сложная задача для злоумышленника.
    
    Если мы не получали отпечаток ключа, или сам ключ напрямую от его владельца, то
    полного доверия к полученному через все эти WKD, DANE и прочих, у
    нас нет. Например, ключевой сервер это одна точка отказа. DANE и TLS используют
    PKI, который может быть скомпрометирован на государственном уровне.
    
    Для того чтобы иметь хоть какое-то доверие, в OpenPGP используется:
    
    Сеть доверия: Web-of-Trust (WoT)
    
    Пользователи могут подписывать публичные ключи друг друга, тем самым заверяя,
    что аутентифицировали ту или иную информацию в ключе (например, видели паспорт
    с прописанным в нём именем, смогли отправить/получить электронную почту по
    указанным в ключе адресам, итд). WoT представляет собой граф таких связей, основанных на
    подписях людей.
    
    В теории, если у вас есть доверенные публичные ключи ваших знакомых, а у
    недоверенного ключа есть их подписи, то скорее всего, ему можно доверять в
    большей степени.
    
    Чем больше подписей он имеет, тем выше вероятность, что среди них есть подписи
    удостоверяемых вами ключей. Для расширения WoT многие часто проводят, так называемые,
    Key Signing Party.
    
    Это не даёт полной гарантии доверия: например, у вас есть известный и доверяемый
    ключ системного администратора вашей компании, и он захочет устроить MitM атаку
    -- если у полученного ранее неизвестного вам ключа будет стоять только его
    подпись, то он успешно её проведёт. GnuPG в WoT находит кратчайший путь доверия
    -- это даёт потенциально множество точек отказа (MitM). Но в теории, ничто не
    мешает аутентифицировать WoT полностью.
    
    Кроме того, через WoT утекает информация о ваших связях, с кем вы так или иначе
    контактировали, виделись, вообще имели хоть какое-то дело. Это приватная
    информация, но из-за WoT она публично доступна. Ценность подобной
    метаинформации может быть огромна.
    
    Модель Trust On First Use (TOFU)
    
    В этой модели все факты успешного использования ключей сохраняются в локальной
    базе данных. При первом использовании ключа он просто запоминается. Далее,
    каждый факт успешной проверки новой подписи с заданного email адреса
    сохраняется в БД. Если для известного email адреса будет замечено использование
    другого ключа, то это повод для предупреждения о возможной MitM атаке.
    
    Чем больше будет успехов использования ключа на заданных адресах, тем выше к
    нему доверие. Если мы регулярно и долго общаемся с человеком и продолжаем
    использовать один и тот же ключ, то выше вероятность доверия к нему.
    
    TOFU предоставляет меньшие гарантий доверия, чем WoT, но его гораздо проще
    использовать, он требует меньше действий от пользователя, так как
    фактически просто собирает статистику. WoT требует аккуратного управления доверием к
    каждому UID-у ключей, созданием подписей и их обменом.
    
    Но TOFU можно использовать и совместно c WoT, как минимум, для обнаружения
    неконсистентной связи используемых ключей и соответствующих email адресов.
    
    Включить режим WoT и TOFU можно опцией: trust-model tofu+pgp.
    
    Полностью ручное управление доверием
    
    В этом случае, вы не полагаетесь ни на статистику (TOFU), ни на WoT, и подписи
    других людей (их можно вообще вырезать из импортируемых ключей для экономии
    места на жёстком диске), а просто самостоятельно в вашей локальной ключнице
    проставляете степень доверия UID-ам ключей. Для большей безопасности вы можете
    подписывать доверяемые UID-ы чужих ключей, но делая локальную подпись, которая
    не попадаёт в экспорт.
    
    Рекомендовать что-то одно конкретное вряд ли можно: везде свои плюсы и минусы,
    где-то удобнее одно, где-то другое, в зависимости от потребностей и возможностей.
    
     
    ----* Отключение SSLv2 для защиты сервера от атаки DROWN (доп. ссылка 1)   [комментарии]
     
    Отключаем SSLv2 для защиты от атаки DROWN, позволяющей с MITM-хоста получить
    доступ к защищённому каналу связи между клиентом и уязвимым сервером.
    Уязвимость проявляется если сервер поддерживает SSLv2 (не важно какой протокол
    используется в текущем сеансе, какая реализация библиотеки шифрования
    используется и какие протоколы поддерживает клиент).
    
    
    Отключение SSLv2 в nginx (в версиях 0.7.64, 0.8.18 и младше SSLv2 включен по умолчанию):
    
       ssl_protocols TLSv1 TLSv1.1 TLSv1.2
    
    
    Отключение SSLv2 в Apache httpd (в httpd 2.2.x и младше SSLv2 включен по умолчанию ):
    
       SSLProtocol All -SSLv2 -SSLv3
    
    Отключение SSLv2 в Postfix (в версиях  2.9.13, 2.10.7, 2.11.5, 3.0.1 и младше
    SSLv2 включен по умолчанию)):
    
        smtpd_tls_protocols = !SSLv2, !SSLv3
        smtp_tls_protocols = !SSLv2, !SSLv3
        lmtp_tls_protocols = !SSLv2, !SSLv3
        tlsproxy_tls_protocols = $smtpd_tls_protocols
    
        smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
        smtp_tls_mandatory_protocols = !SSLv2, !SSLv3
        lmtp_tls_mandatory_protocols = !SSLv2, !SSLv3
        tlsproxy_tls_mandatory_protocols = $smtpd_tls_mandatory_protocols
    
    
        smtpd_tls_ciphers = medium
        smtp_tls_ciphers = medium
    
    
        smtpd_tls_dh1024_param_file=${config_directory}/dh2048.pem
        smtpd_tls_eecdh_grade = strong
    
    
        smtp_tls_exclude_ciphers =
            EXPORT, LOW, MD5,
            aDSS, kECDHe, kECDHr, kDHd, kDHr,
            SEED, IDEA, RC2
        smtpd_tls_exclude_ciphers =
            EXPORT, LOW, MD5, SEED, IDEA, RC2
    
     
    ----* Обфускация структуры полей в базе данных   Автор: 赤熊  [комментарии]
     
    Хорошим примером защиты данных в разных базах является их шифрование. Для
    хранения паролей используют лишь хеш. А хеш, как известно, необратим.
    Нижепредложенный perl-скрипт хорош для огораживания структуры полей таблиц баз
    данных под управлением MySQL 5.x.  Обфускация полей базы вкупе с шифрованием
    данных может минимизировать потери в случае эксплуатации sql-injection
    уязвимостей и утечки данных.
    В качестве аргументов передаётся файл с SQL-дампом структуры БД и "соль" к
    хэшу. На выходе формируется файл с полями, заменёнными на нечитаемые наборы
    символов, что затрудняет определение суть хранимых в полях данных (если данные
    в БД хранятся в зашифрованном виде).
    
    Код ниже:
    
       use Digest::SHA qw(sha256_hex);
       print "-------------------------------------\n";
       print "db_obfuscator started\n";
       if (($#ARGV + 1)<2)
       {
            print "run $0 db_name.sql pass\n";
            print "-------------------------------------\n";
            die;
       }
       my $db_filename = $ARGV[0];
       my $db_filename_out =  $ARGV[0];
       $db_filename_out =~ /(\w+)\.(\w+)/;
       $db_filename_out = $1 . "_out." . $2;
       my $base_hash = sha256_hex($ARGV[1]);
       my $hash_str = $base_hash . "test_str";
       my $text;
       $q = sha256_hex($hash_str);
       #print "$hash_str = $q\n";
    
       $filesize  = -s $db_filename;
       open DB,"<", $db_filename or die "could not open $db_filename\n";
       my $filesize_test = read (DB, $text, $filesize);
       print "read $filesize_test bytes from $db_filename\n";
       close DB;
       my @matches  = ($text =~ /\`[a-z,_,0-9]+\`/g);
       #print "found @matches.lenght() \n";
       foreach $abc(@matches)
       {
            $q = sha256_hex($base_hash.$abc);
            $text =~s/$abc/\`$q\`/g;
       #       print "$abc = $q\n";
       }
       open (outfile, ">", $db_filename_out);
       printf outfile $text or die "could not write $db_filename_out\n";
       close(outfile);
       my $filesize_out = -s $db_filename_out;
       print "wrote $filesize_out bytes into $db_filename_out\n"
    
     
    ----* Получение сертификата через общедоступный удостоверяющий центр LetsEncrypt (доп. ссылка 1) (доп. ссылка 2)   [комментарии]
     
    Удостоверяющий центр LetsEncrypt контролируется сообществом и позволяет
    любому желающему бесплатно получить TLS-сертификат для организации доступа
    через защищённое соединение к своему сайту. Для прохождения верификации перед
    получением сертификата достаточно продемонстрировать контроль над доменом через
    размещения файла с ключом на web-сервере или запуска специального
    автоматизированного крипта.
    
    Инструментарий для верификации домена и управления сертификатами можно загрузить с сайта проекта:
    
       git clone https://github.com/letsencrypt/letsencrypt
       cd letsencrypt
       ./letsencrypt-auto --help
    
    или установить готовые пакеты для Fedora 23:
    
       dnf install letsencrypt
    
    
    Основные методы верификации:
    
    1. Ручной метод: генерация кода подтверждения и его копирование на  web-сервер. 
    Генерируем проверочный код:
    
        letsencrypt --text --email recovery@example.com --domains www.example.com,example.com,foo.example.com --agree-tos --renew-by-default --manual certonly
    
    Записываем полученный код на web-сервер в файл
    .well-known/acme-challenge/anotherrandomthinghere, относительно корня сайта:
    
       cd /var/www/html
       mkdir -p .well-known/acme-challenge
       echo "224234fSDFSF23SFADASD" > .well-known/acme-challenge/anotherrandomthinghere
    
    
    
    2. Самодостаточная проверка: на время проверки letsencrypt берёт на себя
    функции  http-сервера, связанного с верифицируемым доменом (хост, на который
    указывает "A" запись в DNS), и напрямую отвечает на запросы сервиса. На
    сервере, где будет обслуживаться домен запускаем (http-сервер сайта должен быть
    отключен, метод подходит для начальной конфигурации ещё не введённых в строй сайтов):
    
       letsencrypt --text --renew-by-default --email recovery@example.com --domains www.example.com,example.com,foo.example.com --agree-tos --standalone --standalone-supported-challenges http-01 certonly
    
    
    3. Проверка через автоматизированное создание файлов к корне web-сервера. На
    сервере, где работает сайт проверяемого домена, запускаем (/var/www/html - путь
    к корню сайта, относительно которого будут временно размещены коды для верификации):
    
      letsencrypt --text --renew-by-default --email recovery@example.com --domains www.example.com,example.com,foo.example.com --agree-tos --webroot --webroot-path /var/www/html certonly
    
    При выполнении автоматизированной проверки от пользователя root готовые
    сертификаты будут скопированы в директорию /etc/letsencrypt. Для их подключения
    к mod_ssl можно выполнить:
    
    
       ln -s /etc/letsencrypt/live/www.example.com/cert.pem /etc/pki/tls/certs/www.example.com.crt
       ln -s /etc/letsencrypt/live/www.example.com/chain.pem /etc/pki/tls/certs/www.example.com.chain.crt
       ln -s /etc/letsencrypt/live/www.example.com/privkey.pem /etc/pki/tls/private/www.example.com.key
       cp /etc/httpd/conf.d/ssl.conf{,.backup}
       sed -i 's@\(SSLCertificateFile\) .*@\1 /etc/pki/tls/certs/www.example.com.crt@' /etc/httpd/conf.d/ssl.conf
       sed -i 's@\(SSLCertificateKeyFile\) .*@\1 /etc/pki/tls/private/www.example.com.key@' /etc/httpd/conf.d/ssl.conf
       sed -i 's@#\(SSLCertificateChainFile\) .*@\1 /etc/pki/tls/certs/www.example.com.chain.crt@' /etc/httpd/conf.d/ssl.conf
    
    
    После чего нужно сделать директории с сертификатами доступными в SELinux-контексте cert_t:
    
       semanage fcontext -a -t cert_t '/etc/letsencrypt/(archive|live)(/.*)?'
       restorecon -Rv /etc/letsencrypt
    
    По умолчанию время жизни сертификата LetsEncrypt составляет 90 дней, что
    требует настройки автоматизации обновления сертификата. Например, раз в 60 дней
    через cron можно вызывать скрипт, который будет продлевать сертификат на
    очередные 90 дней:
    
       /usr/bin/letsencrypt -d www.example.com --renew-by-default -m recovery@example.com --agree-tos -t --webroot -w /var/www/html certonly
    
    Пример unit-файла /etc/systemd/system/www-example-com-renewal.service для обновления сертификатов:
    
    
       [Unit]
       Description=Automatically renew the www.example.com certificate
    
       [Service]
       Type=oneshot
       ExecStart=/usr/bin/letsencrypt -d www.example.com --renew-by-default -m recovery@example.com --agree-tos -t --webroot -w /var/www/html certonly
       ExecStart=/usr/sbin/systemctl reload httpd
    
    
    Файл автозапуска /etc/systemd/system/www-example-com-renewal.timer:
    
       [Unit]
       Description=Trigger an automatic renewal every month
    
       [Timer] 
       OnCalendar=monthly
       Persistent=true
    
       [Install]
       WantedBy=multi-user.target
    
    В случае необходимости отзыва сертификата, например, после утечки закрытых
    ключей, можно выполнить команду:
    
       letsencrypt revoke --cert-path /etc/letsencrypt/archive/www.example.com/cert1.pem
    
    
    Для упрощения работы с сервисом можно использовать скрипт-обвязку https://github.com/lukas2511/letsencrypt.sh
    
     
    ----* Настройка SSH для использования наиболее защищённых алгоритмов шифрования (доп. ссылка 1)   [комментарии]
     
    В свете появления сведений об организации АНБ атак, направленных на
    получение контроля над SSH-соединениями, подготовлено руководство с
    рекомендациями по усилению защищённости SSH. АНБ может получить контроль за
    SSH-соединением  в случае использования уязвимых методов шифрования или в
    результате захвата приватных ключей. Ниже представлены советы по отключению
    потенциально проблемных алгоритмов и усилению защиты.
    
    
    Обмен ключами.
    
    Применяемые в SSH методы обмена ключей  DH (Diffie-Hellman) и ECDH (Elliptic
    Curve Diffie-Hellman) можно считать безопасными. Из 8 поддерживаемых в SSH
    протоколов обмена ключами вызывают подозрения три,  основанные на рекомендациях
    NIST: ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521. Не
    заслуживающими полного доверия также можно считать протоколы, использующие
    потенциально проблемный SHA1. Протоколы curve25519-sha256 и diffie-hellman-group-exchange-sha256
     пока не вызывают сомнений в безопасности.
    
    Для использования только заслуживающих доверия протоколов обмена ключами в
    /etc/ssh/sshd_config  для сервера следует указать:
    
        KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256
    
    Аналогичные настройки для клиента, в /etc/ssh/ssh_config:
    
       Host *
          KexAlgorithms curve25519-sha256@libssh.org,diffie-hellman-group-exchange-sha256
    
    В /etc/ssh/moduli можно указать (или удалить строки с размером ключа, менее 2048):
    
       ssh-keygen -G /tmp/moduli -b 4096
       ssh-keygen -T /etc/ssh/moduli -f /tmp/moduli
    
    
    Аутентификация.
    
    В SSH поддерживается четыре алгоритма аутентификации по открытым ключам: DSA,
    ECDSA,  Ed25519 и RSA. ECDSA завязан на технологиях NIST и должен быть
    отключен. К сожалению, если просто удалить ключ ECDSA, он будет повторно
    сгенерирован, поэтому можно воспользоваться обходным путём с создать заведомо
    нерабочую символическую ссылку, которая помешает сгенерировать и использовать ключ:
    
       cd /etc/ssh
       rm ssh_host_ecdsa_key*
       rm ssh_host_key*
       ln -s ssh_host_ecdsa_key ssh_host_ecdsa_key
       ln -s ssh_host_key ssh_host_key
    
    Так как размер ключей DSA  не может превышать 1024, его тоже следует отключить тем же способом:
    
       cd /etc/ssh
       rm ssh_host_dsa_key*
       ln -s ssh_host_dsa_key ssh_host_dsa_key
    
    Далее, следует позаботиться о RSA, сгенерировав ключ большего размера:
    
       cd /etc/ssh
       rm ssh_host_rsa_key*
       ssh-keygen -t rsa -b 4096 -f ssh_host_rsa_key < /dev/null
    
    Для создания клиентских ключей лучше использовать команды:
    
       ssh-keygen -t ed25519
       ssh-keygen -t rsa -b 4096
    
    
    Симметричные шифры.
    
    Из 15 поддерживаемых в SSH алгоритмов симметричного шифрования, используемых
    для организации защиты установленного канала связи, безопасными можно считать
    chacha20-poly1305, aes*-ctr и aes*-gcm. Шифры 3des-cbc и arcfour потенциально
    уязвимы в силу использования DES и RC4, cast128-cbc применяет слишком короткий
    размер блока (64 бит).
    
    В итоге, в /etc/ssh/sshd_config рекомендуется добавить:
    
       Ciphers aes256-gcm@openssh.com,aes128-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
    
    В /etc/ssh/ssh_config:
    
       Host *
          Ciphers aes256-gcm@openssh.com,aes128-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
    
    Код аутентичности сообщения (MAC).
    
    Для шифров в режиме  CTR для гарантирования  целостности передаваемых блоков
    доверия заслуживает только метод Encrypt-then-MAC ("*-etm", MAC добавляется  к
    уже зашифрованному блоку). Методы MAC-then-encrypt и Encrypt-and-MAC
    потенциально подвержены атакам. Из 18 доступных в SSH алгоритмов MAC  сразу
    следует отбросить основанные на хэшах  MD5 и SHA1, не стойких к выявлению
    коллизий, а также алгоритмы использующие размеры ключей менее 128 бит и размеры
    тегов менее 256 бит. В итоге, наиболее безопасными MAC  можно считать
    hmac-sha2-512-etm и hmac-sha2-256-etm.
    
    В /etc/ssh/sshd_config:
    
       MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
    
    В /etc/ssh/ssh_config:
    
       # Для GitHub в качестве исключения добавляем mac-sha2-512, так как он не поддерживает Encrypt-then-MAC.
       Host github.com
           MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512
    
       Host *
          MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
    
    
    Защита от утечки ключей.
    
    Наиболее простым способом получения контроля за SSH-соединением является захват
    ключей на стороне клиента или сервера. Рекомендации сводятся к соблюдению
    типовых правил поддержания безопасности системы: оперативная установка
    обновлений, установка программ только из надёжных источников, установка только
    действительно необходимых программ и сервисов, использование программ для
    которых доступны исходные тексты, включение дополнительных механизмов защиты
    (Grsecurity, сборка с флагом -fstack-protector).
    
    Для защиты ключей следует выбрать надёжный пароль доступа к клиентским файлам
    ключей. При формировании ключа для увеличения числа итераций хэширования можно
    использовать опцию "ssh-keygen -o -a число", что  усложнит подбор пароля. Также
    можно сохранить ключи только на внешнем носителе, подключая его только во время
    соединения по SSH.
    
    Защита от анализа транзитного трафика.
    
    SSH-сервер можно настроить в виде скрытого сервиса Tor, что скроет IP, а также
    добавит дополнительный слой шифрования и аутентификации.
    
    Для приема соединений только через скрытый сервис Tor можно использовать следующие настройки:
    
    В /etc/ssh/sshd_config (для приема соединений из LAN следует вместо привязки к
    127.0.0.1 использовать для ограничения доступа межетевой экран):
    
       ListenAddress 127.0.0.1:22
    
    В /etc/tor/torrc добавим:
    
       HiddenServiceDir /var/lib/tor/hidden_service/ssh
       HiddenServicePort 22 127.0.0.1:22
    
    Имя скрытого хоста для подключения можно найти в файле /var/lib/tor/hidden_service/ssh/hostname. 
    
    Для настройки подключения клиента к скрытому сервису Tor в  /etc/ssh/ssh_config можно добавить:
    
       Host *.onion
           ProxyCommand socat - SOCKS4A:localhost:%h:%p,socksport=9050
    
     
    ----* Добавление поддержки SSL в pgbouncer при помощи stunnel   Автор: umask  [комментарии]
     
    Для быстрого старта pgbouncer c поддержкой SSL можно использовать вот такой
    конфигурационный файл stunnel:
    
       ### stunnel config for ssl-before-pgbouncer
       
       ### Quick way to create stunnel.pem:
       ### cd /etc/stunnel
       ### openssl req -new -x509 -days 77777 -nodes -out stunnel.pem -keyout stunnel.pem
       ### openssl gendh 2048 >> stunnel.pem
       ### openssl x509 -subject -dates -fingerprint -in stunnel.pem
    
       cert = /etc/stunnel/stunnel.pem
       foreground = yes
       setgid = nobody
       setuid = nobody
       pid = /tmp/stunnel.pid
       compression = zlib
       ### use this level to prevent trashing logs
       #debug = 4
       
       [psqlssl]
       ### stunnel will listen here
       accept = 127.0.0.1:9933
       ### pgbouncer listen here
       connect = 127.0.0.1:5433
       protocol = pgsql
    
    Версия stunnel должна быть не ниже 4.27, так как только начиная с данной версии
    есть поддержка protocol = pgsql.
    
    Основная необходимость в SSL в моём случае - сжатие, а не шифрование. 
    
     
    ----* Включение в Fedora и CentOS поддержки шифрования по эллиптическим кривым (доп. ссылка 1) (доп. ссылка 2)   [комментарии]
     
    По умолчанию в Fedora и CentOS пакет OpenSSL собран без поддержки криптографии
    по эллиптическим кривым (ECC,  Elliptic Curve Crytography), так как реализация
    потенциально нарушает ряд патентов. В Debian и Ubuntu пакет openssl
    собран с поддержкой ECC.
    
    На конференции Black Hat USA 2013 группа экспертов по криптографии представила
    результаты исследования, в результате которого был сделан вывод, что время
    алгоритма RSA сочтено и пока не поздно вендорам следует перейти на
    использовании криптографии по эллиптическим кривым. С учётом развития методов
    ускорения векторных вычислений, уже через пять лет RSA нельзя будет считать безопасным.
    
    
    Пересборка OpenSSL и strongSwan (IPSec) в Fedora.
    
    
    Удаляем пакет openssl-devel и устанавливаем пакеты, необходимые для сборки:
    
       rpm -e openssl-devel
       yum install rpm-build krb5-devel zlib-devel gcc \\
          gmp-devel libcurl-devel openldap-devel \\
          NetworkManager-devel NetworkManager-glib-devel sqlite-devel
    
    Подготавливаем сборочное окружение rpmbuild:
    
       [ ! -e ~/.rpmmacros ] && \\
           echo '%_topdir      %(echo $HOME)/rpmbuild' > ~/.rpmmacros
       [ ! -d rpmbuild ] && mkdir rpmbuild
       cd ~/rpmbuild
       mkdir -p BUILD BUILDROOT RPMS/i386 RPMS/x86_64 SOURCES SPECS SRPMS
    
    
    Загружаем src-пакет, заменяем изменённые исходные тексты на оригинальный
    openssl и применяем патч для включения сборки с ECC:
    
    
       cd ~/rpmbuild/SRPMS
       wget http://dl.fedoraproject.org/pub/fedora/linux/releases/19/Everything/source/SRPMS/o/openssl-1.0.1e-4.fc19.src.rpm
       rpm -i openssl-1.0.1e-4.fc19.src.rpm
       cd ../SOURCES
       wget http://www.openssl.org/source/openssl-1.0.1e.tar.gz
       cd ../SPECS
       wget http://zxvdr.fedorapeople.org/openssl.spec.ec_patch
       patch -p0 < openssl.spec.ec_patch
       sed -i -e 's/-usa.tar.xz/.tar.gz/' openssl.spec
       rpmbuild -bb openssl.spec
    
    Устанавливаем собранный  OpenSSL:
    
       cd ~/rpmbuild/RPMS/$(uname -i)
       rpm -Uvh --force \\
           openssl-1.0.1e*rpm \\
           openssl-devel-1.0.1e*rpm \\
           openssl-libs-1.0.1e*rpm
    
    Проверяем поддержку ECC:
    
       openssl ec -help
    
    Пересобираем strongSwan, при наличии поддержки ECC в OpenSSL при пересборке
    strongSwan автоматически определит наличие ECC:
    
       wget http://dl.fedoraproject.org/pub/fedora/linux/releases/19/Everything/source/SRPMS/s/strongswan-5.0.2-2.fc19.src.rpm
       rpm -i strongswan-5.0.2-2.fc19.src.rpm
       cd ~/rpmbuild/SPECS
       rpmbuild -bb strongswan.spec
    
    Устанавливаем strongSwan:
    
       cd ~/rpmbuild/RPMS/$(uname -i)
       rpm -Uvh --force \\
          strongswan-5*rpm \\
          strongswan-tnc-imcvs*rpm
    
    Проверяем strongSwan, пытаясь создать ECDSA-ключ:
    
       cd /tmp
       strongswan pki -g --type ecdsa --size 384 > myKey.der
       strongswan pki -a --type ecdsa-priv --in myKey.der
    
       private key with:
       pubkey:    ECDSA 384 bits
     
    
    Инструкция для CentOS 6.4
    
    Формируем сборочное окружение
    
       yum -y update
       yum -y groupinstall 'Development tools'
    
    Подключаем репозиторий EPEL 
       yum -y localinstall --nogpgcheck http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm 
    
    Устанавливаем и настраиваем сборочный инструментарий mock из EPEL:
    
       yum -y install fedora-packager
       userdel -rf abcd
       useradd -G mock abcd
       su abcd
    
    Загружаем src-пакет и оригинал openssl 
    
       cd ~
       curl -O http://vault.centos.org/6.4/os/Source/SPackages/openssl-1.0.0-27.el6.src.rpm
       /usr/bin/mock ~/openssl-1.0.0-27.el6.src.rpm
       rm -rf /home/abcd/build
       mv /var/lib/mock/epel-6-x86_64/root/builddir/build/ /home/abcd 
       cd /home/abcd/build/SOURCES
       curl -O http://www.openssl.org/source/openssl-1.0.0.tar.gz 
    
    Загружаем патч, устраняющий вывод ошибки при выполнении тестов
    
       curl -o patch300.patch http://cvs.openssl.org/patchset?cn=19998 
    
    Правим spec-файл, включаем режим enable-ec, отключаем скрипт hobble и добавляем патч:
    
       cd ../SPECS
       sed -i -e "s/no-ec/enable-ec/; s/no-ecdh/enable-ecdh/; s/no-ecdsa/enable-ecdsa/" openssl.spec
       sed -i -e "s/^Source1: hobble-openssl/#&/; s/^%.SOURCE1. /#&/" openssl.spec
       sed -i -e "s/^Release.*dist\\}/&.EC.1/" openssl.spec 
       sed -i -e "s/-usa.tar.bz2/.tar.gz/" openssl.spec 
       sed -i -e "s/^Patch78.*/&\\nPatch300: patch300.patch\\n/" openssl.spec
       sed -i -e "s/^%patch78.*/&\\n%patch300 -p1 \\n/" openssl.spec 
    
    Пересобираем пакет:
    
       /usr/bin/mock --buildsrpm --spec  ~/build/SPECS/openssl.spec --sources  ~/build/SOURCES 
       cp /var/lib/mock/epel-6-x86_64/root/builddir/build/SRPMS/openssl-1.0.0-27.el6.EC.1.src.rpm /home/abcd
       cd ~
       /usr/bin/mock --rebuild openssl-1.0.0-27.el6.EC.1.src.rpm
     
    
     
    ----* Создание канала связи с использованием TLS-SRP из состава OpenSSL 1.0.1 (доп. ссылка 1)   [комментарии]
     
    Для создания шифрованного канала связи с использованием вместо ключей
    шифрования обычных паролей, которые может запомнить человек, можно использовать
    протокол SRP (Secure Remote Password), поддержка которого появилась в OpenSSL 1.0.1.
    
    Создаём файл с SRP паролем для пользователя jsmith:
    
       touch passwd.srpv
       openssl srp -srpvfile passwd.srpv -gn 1536 -add jsmith
     
       вводим дважды пароль
    
    Для изменения пароля можно использовать команду:
    
       openssl srp -srpvfile passwd.srpv -modify jsmith
    
    Запускаем простой SRP-сервер:
    
       openssl s_server -srpvfile passwd.srpv -tls1 -cipher SRP -cert server.crt -key server.key -www
    
    Соединяемся к нему по сетевому порту 4433:
    
       gnutls-cli --srpusername user --srppasswd secret 127.0.0.1 -p 4433
    
       вводим "GET /"
    
    Для соединения также можно использовать openssl_helper из состава Chromium:
    
       out/Debug/openssl_helper open-socket tls-srp --srpv-file net/data/ssl/certificates/ok.srpv --port 4443
    
    логин/пароль задаётся в файле ok.srpv
    
     
    ----* Использование TRESOR для хранения ключей шифрования AES не в ОЗУ, а в регистрах CPU (доп. ссылка 1)   [комментарии]
     
    При использовании зашифрованного раздела с конфиденциальной информацией,
    злоумышленник, имеющий физический доступ к компьютеру, может воспользоваться
    методом холодной перезагрузки
    (http://www.opennet.dev/opennews/art.shtml?num=17035) для получения ключей
    шифрования. Метод основан на способности оперативной памяти (DRAM) какое-то
    время сохранять информацию после отключения питания и отсутствия импульсов
    регенерации ее содержимого (при температуре -50 градусов данные сохраняются
    более 10 минут). После холодной перезагрузки или переключении чипа памяти на
    другое устройство память не обнуляется и данные старой рабочей сессии можно
    проанализировать. Особенно актуальная проблема для ноутбуков, которые часто не
    выключаются и лишь переводятся в ждущий режим, при котором ОЗУ не
    обесточивается. В простейшем случае, восстановить ключ из памяти можно
    используя утилиту msramdmp (http://www.mcgrewsecurity.com/tools/msramdmp/),
    перезагрузившись в LiveCD (например, можно использовать msramdmp_cd.iso).
    
    В рамках проекта TRESOR (http://www1.informatik.uni-erlangen.de/tresor)
    подготовлены патчи для ядра Linux с реализацией модуля шифрования AES, который
    сохраняет ключи в отладочных регистрах процессора и обрабатывает все операции
    шифрования непосредственно в CPU, без копирования ключей в ОЗУ. TRESOR  может
    использоваться на любых процессорах с поддержкой SSE2. При использовании
    64-разрядных CPU с поддержкой набора инструкций AES-NI,  например, Intel Core
    i5 или Core-i7, поддерживается работа с ключами AES 128, 192 и 256 без потери
    производительности. При запуске на 32-разрядных CPU с поддержкой инструкций
    SSE2, скорость выполнения шифрования примерно в 6 раз ниже, чем базовая
    реализация AES для ядра Linux. При этом можно использовать только ключи длиной
    128 бит.
    
    Собираем ядро с патчем TRESOR.
    
    Загружаем ядро 2.6.36 с http://kernel.org и распаковываем его в директорию /usr/src/linux-2.6.36.
    
    Применяем патч (http://www1.informatik.uni-erlangen.de/tresor):
    
       cd /usr/src/
       patch --directory /usr/src/linux-2.6.36 -p1 < tresor-patch-2.6.36
    
    Запускаем menuconfig и настраиваем параметры ядра, не забыв включить TRESOR
    (Cryptographic API -> AES cipher algorithms (TRESOR)).
    
    Собираем ядро. Ниже пример сборки и установки пакета для Debian GNU/Linux:
    
       cd /usr/src/linux-2.6.36
       make-kpkg kernel_image --initrd --revision tresor1
       cd /usr/src
       dpkg -i linux-image-2.6.36-tresor1.deb
       update-initramfs -c -k 2.6.36
    
    
    Запускаем систему
    
    Перезагружаемся, выбрав ядро с патчами TRESOR.
    
    В ответ на приглашение TRESOR "Enter password" вводим пароль и подтверждаем валидность хэша:
    
       Enter password > ******** 
       Confirm key hash > 51 b7 fd ... 58 ac Correct (yes/no) > yes
    
    Пароль может содержать от 8 до 53 символов. Возможности поменять пароль после
    загрузки нет, поэтому к вводу пароля нужно отнестись внимательно иначе
    потребуется лишний раз перезагружать систему. Выводимый хэш не является ключом
    шифрования, а просто выводится для того чтобы можно было дополнительно
    проверить правильность задания пароля.
    
    После того как система загрузится можно попытаться перевести её в ждущий режим
    и проверить работу TRESOR:
    
       echo mem > /sys/power/state
    
    После возвращения из спящего режима должно быть выведено приглашение для ввода
    пароля, такое же как после загрузки системы. Для проверки, что повторно
    введенный пароль верен в памяти сохраняется необратимый проверочный хэш,
    который позволяет удостовериться в правильности ввода, но не дает возможности
    восстановить содержимое пароля и ключа шифрования. Проверка пароля необходима,
    так как неправильно введенный пароль может привести к повреждению данных в уже
    примонтированном зашифрованном разделе. Так как пароль вводится в консоли при
    активном графическом режиме возможно потребуется ввести пароль вслепую.
    
    
    Настройка шифрования
    
    Устанавливаем утилиты для работы с dm-crypt:
    
       apt-get install cryptsetup
    
    Если ядро собрано с поддержкой LKM, убедимся, что загружен модуль ядра dm_mod:
    
       modprobe dm_mod
    
    В качестве демонстрации настроим два варианта шифрования: отдельного раздела на
    USB-накопителе и виртуального шифрованного раздела внутри файла.
    
    
    Настройка зашифрованного дискового раздела
    
    Зашифруем раздел /dev/sdb1: 
    
       cryptsetup create tresor /dev/sdb1 --cipher tresor --key-size 128
    
       > Enter passphrase: указываем произвольный пароль
    
    Размер ключа для 64-разрядных процессоров с поддержкой AES-NI может быть 128,
    192 и 256. Для остальных CPU - только 128.
    
    Форматируем созданный шифрованный раздел:
    
       mkfs.ext2 /dev/mapper/tresor
    
    Монтируем раздел:
    
       mount /dev/mapper/tresor /media/tresor
    
    все операции записи и чтения в /media/tresor производятся с использованием шифрования.
    
    Отмонтируем раздел и выгружаем шифрованное устройство:
    
       umount /media/tresor
       cryptsetup remove tresor
    
    Настройка зашифрованного контейнера (шифрованный раздел внутри файла)
    
    Создаем пустой файл-контейнер container.img, размером 1 Гб:
    
       dd if=/dev/zero bs=1M count=1024 of=container.img
    
    Прикрепляем контейнер к псевдоустройству через loop-интерфейс:
    
       losetup /dev/loop0 container.img
    
    Повторяем действия, описанные выше для шифрованных дисковых разделов, но
    используя в качестве имени устройства /dev/loop0
    
    При отмонтировании, для отсоединения контейнера от loop-устройства дополнительно выполняем:
    
       losetup -d /dev/loop0 
    
     
    ----* Перехват WEP и WPA ключей в беспроводной сети при помощи AIR Crack  (доп. ссылка 1) (доп. ссылка 2)   [комментарии]
     
    Инструкция по подбору ключей шифрования в беспроводных сетях, базирующихся на
    механизме WEP, являющемся устаревшим, но продолжающем широко использоваться.
    Данная информация предназначена только для ознакомления и может быть
    использована исключительно в целях проверки надежности собственной сетевой инфраструктуры.
    
    Устанавливаем пакет AIR Crack.
    В Debian/Ubuntu:
    
       $ sudo apt-get install aircrack-ng
    
    В Fedora/CentOS/RHEL:
    
       $ sudo yum -y install aircrack-ng
    
    Определяем сетевой интерфейс, привязанный к беспроводной карте:
    2. Identify wireless network interface
    
       $ /sbin/iwconfig
    
       wlan0     IEEE 802.11  Mode:Monitor  Frequency:2.437 GHz  Tx-Power=20 dBm
    
    Активируем режим мониторинга:
    
       $ sudo airmon-ng start wlan0
    
       Interface       Chipset         Driver
       wlan0                   rtl8180 - [phy0]
       (monitor mode enabled on mon0)
    
    Определяем BSSID-идентификатор сети:
    
       $ sudo airodump-ng wlan0
    
       BASE:
       BSSID : 00:0F:B5:FD:FB:C2
       Channel: 6
       STATION:
       MAC: 00:13:04:30:FA:EC
    
    Для успешного проведения атаки к точке доступа должна быть подключена хотя бы
    одна активная машина, чем больше трафик у которой, тем быстрее будет подобран ключ.
    
    Включаем режим снифинга и накапливаем статистику. Чем длиннее WEP-ключ тем
    больше пакетов необходимо перехватить (64-битный ключ требует накопления
    примерно 6000 пакетов):
    
       $ sudo airodump-ng -c 6 --bssid 00:0F:B5:FD:FB:C2 -w data-capture wlan0
    
    где, "-c 6" - номер канала беспроводной точки доступа (см. вывод airodump-ng
    wlan0). В опции --bssid указан идентификатор точки доступа, для отсеивания
    лишнего трафика. Все перехваченные пакеты будут сохранены в файле data-capture-01.cap.
    
    После накопления достаточного объема статистики подбираем WEP-ключ (выполняем
    операцию не прерывая процесс снифинга, так как числа перехваченных пакетов
    может не хватить):
    
       $ sudo aircrack-ng -z data-capture-01.cap
    
       Opening data-capture-01.cap
       Read 450 packets.
    
       #  BSSID              ESSID                     Encryption
       1  00:11:95:35:FD:12  test1                WEP (210 IVs)
       2  00:17:3F:62:2E:50  test2                None (0.0.0.0)
    
        Index number of target network ? 1
    
       [00:00:21] Tested 485 keys (got 17690 IVs)
    
       KB    depth   byte(vote)
        0    9/ 13   00(20993) 06(20737) 27(20736) 3F(20736) A2(20736)
        1    0/  1   F3(28417) A8(23298) 34(21248) 57(21248) A3(21248)
        2    0/  2   8E(25857) BC(23809) 3F(23040) D2(22784) 69(21504)
        3    0/  5   6E(24321) 35(2259) 5A(22016) 95(22016) B8(22016)
        4    3/  4   98(21505) 7C(20993) 84(20992) E0(20992) F0(20992)
    
       KEY FOUND! [ 1F:F3:6E:6A:98 ]
       Decrypted correctly: 100%
    
    На выходе получили искомый ключ "1F:F3:6E:6A:98".
    
    
    Подбор простого словарного pre-shared WPA-ключа.
    
    Похожим образом осуществляется подбор WPA-ключа, только для успешного
    завершения подбора требуется значительно больше времени и определенное везение.
    
    После запуска  airodump-ng дожидаемся соединения клиента к сети:
    
       CH  6 ][ Elapsed: 4 s ][ 2007-03-24 16:58 ][ WPA handshake: 00:14:6C:7E:40:80
       ...
        BSSID              STATION            PWR  Lost  Packets  Probes                                             
        00:14:6C:7E:40:80  00:0F:B5:FD:FB:C2   35     0      116  
    
    После чего инициируем деаутентификацию клиента:
    
       $ sudo aireplay-ng -0 1 -a 00:14:6C:7E:40:80 -c 00:0F:B5:FD:FB:C2 ath0
    
       11:09:28  Sending DeAuth to station   -- STMAC: [00:0F:B5:34:30:30]
    
    где, 1 - число отправленных deauth-пакетов, 00:14:6C:7E:40:80 - MAC точки
    доступа, 00:0F:B5:FD:FB:C2  - MAC клиента.
    
    Запускаем процесс подбора ключевой фразы по словарю password.lst.
    
       $ aircrack-ng -w password.lst -b 00:14:6C:7E:40:80 data-capture-01.cap
    
    В случае успеха получаем примерно следующее:
     
       BSSID              ESSID                     Encryption
        1  00:14:6C:7E:40:80  teddy                     WPA (1 handshake)
       
       Choosing first network as target.
       ...
       [00:00:00] 2 keys tested (37.20 k/s)
       KEY FOUND! [ 12345678 ]
     
       Master Key     : CD 69 ...
       Transcient Key : 06 F8 ... 
       EAPOL HMAC     : 4E 27 ...
    
     
    ----* IPSec туннель между Cisco и CentOS Linux   Автор: PsV  [комментарии]
     
    Имеем:
    
    1 Маршрутизатор Cisco 5510 ASA с реальным IP 1.1.1.1 (сеть XXX.XXX.0.0/24)
    2. Маршрутизатор Linux CentOS 5.2 (ядро 2.6.18-92.el5) с установленным
    ipsec-tools-0.6.5-13.el5_3.1 и реальным IP 2.2.2.2 (сеть XXX.XXX.0.0/16)
    
    Конфигурация на маршрутизаторе Cisco:
    
       crypto isakmp policy 5
        encr aes
        authentication pre-share
        group 2
        lifetime 3600
        hash sha
       !
       crypto isakmp key SECRETKEY address 2.2.2.2
       crypto ipsec security-association lifetime seconds 3600
       crypto ipsec transform-set GK esp-aes esp-sha-hmac
       crypto map IPSec 7 ipsec-isakmp
       set peer 2.2.2.2
       set transform-set GK
       set pfs group2
       match address 666
      !
      interface GigabitEthernet0/0.1
       ip address 1.1.1.1 255.255.255.224
       crypto map IPSec
      !
      ip route XXX.XXX.0.0 255.255.255.0 2.2.2.2
      access-list 666 remark asGK
      access-list 666 permit ip  XXX.XXX.0.0 0.0.255.255  XXX.XXX.0.0 0.0.0.255
      access-list 666 deny   ip any any
    
    
    Конфигурация на машине с Linux CentOS:
    
    /etc/sysconfig/network-scripts/ifcfg-ipsec0
    
       TYPE=IPSEC
       ONBOOT=yes
       IKE_METHOD=PSK
       IKE_PSK=SECRETKEY
       IKE_DHGROUP=2
       ESP_PROTO=aes
       AH_PROTO=none
       AESP_PROTO=hmac-sha1
       SRC=2.2.2.2
       SRCGW=XXX.XXX.0.100
       DSTGW=1.1.1.1
       SRCNET=XXX.XXX.0.0/24
       DSTNET=XXX.XXX.0/16
       DST=1.1.1.1
    
    
    /etc/racoon/racoon.conf
    
       path include "/etc/racoon";
       path pre_shared_key "/etc/racoon/psk.txt";
       log notify;
    
       listen
       {
          isakmp 2.2.2.2 [500];
       }
    
       sainfo address  XXX.XXX.0.0/24 any address XXX.XXX.0.0/16 any
       {
           pfs_group 2;
           lifetime time 6400 sec;
           encryption_algorithm aes;
           authentication_algorithm hmac_sha1;
           compression_algorithm deflate;
       }
    
    
    и не забываем про iptables!!
    
    после настройки
    
       #ifup ipsec0
    
    после поднятия ipsec0 можно посмотреть есть ли туннель
    
       #setkey -D
    
       2.2.2.2 1.1.1.1
           esp mode=tunnel spi=3839224802(0xe4d5ebe2) reqid=0(0x00000000)
           E: aes-cbc  c98674dd c1cda3a8 36f39eb5 84fd56b4 192e4acd 7ad470d7 0176919b c955cc38
           A: hmac-sha1  d8e6305b 8b0352ab 249d125f 1515e6a8 136d8896
           seq=0x00000000 replay=4 flags=0x00000000 state=mature
           created: Jul  8 10:19:23 2010 current: Jul  8 10:44:57 2010
           diff: 1534(s)   hard: 86400(s)  soft: 69120(s)
           last: Jul  8 10:19:27 2010    hard: 0(s)        soft: 0(s)
           current: 2160(bytes)    hard: 0(bytes)  soft: 0(bytes)
           allocated: 18   hard: 0 soft: 0
           sadb_seq=1 pid=8863 refcnt=0
       1.1.1.1 2.2.2.2
           esp mode=tunnel spi=111533039(0x06a5dbef) reqid=0(0x00000000)
           E: aes-cbc  3e1f5040 cf6c15d2 8083dc28 aa6006ef df53337f 13b31da2 2782ef5c e46d3567
           A: hmac-sha1  a9553dd3 e9b431a5 534baef8 a2b1f34b cc2b8867
           seq=0x00000000 replay=4 flags=0x00000000 state=mature
           created: Jul  8 10:19:23 2010 current: Jul  8 10:44:57 2010
           diff: 1534(s)   hard: 86400(s)  soft: 69120(s)
           last: Jul  8 10:19:27 2010    hard: 0(s)        soft: 0(s)
           current: 833(bytes)     hard: 0(bytes)  soft: 0(bytes)
           allocated: 18   hard: 0 soft: 0
           sadb_seq=0 pid=8863 refcnt=0
    
    
    Ссылки:
           http://www.opennet.dev/base/cisco/cisco_ipsec_freebsd.txt.html (очень помогла эта статья)
           http://netbsd.gw.com/cgi-bin/man-cgi?racoon++NetBSD-current
    
     
    ----* Добавление сертификата в Chromium (доп. ссылка 1) (доп. ссылка 2)   Автор: silverghost  [комментарии]
     
    После установки Chromium потребовалось импортировать сертификат для работы с
    Webmoney Light. В документации к Chromium рекомендуют использовать команду:
    
       certutil -d sql:$HOME/.pki/nssdb -A -t "P,," -n "WebMoney" -i ./wm.p12
    
    Но такая команда выдает ошибку, по крайней мере в Ubuntu 10.04:
    
       certutil: could not obtain certificate from file: security library: invalid arguments.
    
    Решается эта проблема путем использования другой утилиты:
    
       pk12util -d sql:$HOME/.pki/nssdb -i ./wm.p12
    
    Вышеупомянутые утилиты входят в состав пакета libnss3-tools в Ubuntu/Debian,
    nss-tools в Fedora/RHEL и mozilla-nss-tools в openSUSE.
    
     
    ----* Динамическое подключение шифрованных дисковых разделов   Автор: simplexe  [комментарии]
     
    Задача: Обеспечить шифрование централизованного хранилища с хранением ключей
    шифрования на внешнем USB-носителе (воткнул ключ - работает, вытащил - не
    работает). Пакет truecrypt не подошел из-за особенностей его лицензии и
    отсутствия во многих дистрибутивах. Для шифрования было решено использовать
    dm-crypt, из двух фронтэндов cryptsetup и cryptmount был выбран первый.
    
    
    1. Создаем ключ.
    
    Берём обычный Flash-накопитель на базе интерфейса USB, любого размера.
    Форматируем его в vfat и монтируем:
    
       sudo su -
       mkfs.vfat /dev/sdd1
       mkdir /mnt/usbkey
       mount /dev/sdd1 /mnt/usbkey
    
    Теперь, на него нужно скопировать будущий ключ:
    
       dd if=/dev/random of=/mnt/usbkey/public.key bs=1 count=256
    
    Тут думаю все понятно. Теперь, ключ готов и он на флэшке.
    
    
    2. Шифрование тома.
    У меня хранилище на зеркальном программном RAID'е. У вас может быть по-другому, но смысл тот же:
    
       cryptsetup --verbose -c aes-cbc-essiv:sha256 luksFormat /dev/md0 /mnt/usbkey/public.key
    
    Том зашифрован, подключаем его:
    
       cryptsetup --key-file /mnt/usbkey/public.key luksOpen /dev/md0 public
    
    Ну и форматируем:
    
       mkfs.ext3 -j -m 1 -O dir_index,sparse_super /dev/mapper/public
    
    Всё, он готов.
    
    3. Автомонтирование
    
    После чтения документации, консультаций на irc-канале #archlinux-ru  и
    экспериментов, был подготовлен следующий вариант файла конфигурации для udev /etc/udev/rules.d/10-usb-storage.rules:
    
       # если не sd уходим
       KERNEL!="sd[a-z][0-9]", GOTO="end"
       # если переменная существует, то отмонтируем /public
       ACTION=="remove", ENV{dir_name}=="?*", RUN+="/bin/umount -l /public"
       # если переменная существует, то закрываем ключ
       ACTION=="remove", ENV{dir_name}=="?*", RUN+="/sbin/cryptsetup luksClose public"
       # если переменная существует, то отмонтируем саму флэш
       ACTION=="remove", ENV{dir_name}=="?*", RUN+="/bin/umount -l /mnt/%E{dir_name}"
       # если переменная существует, то удаляем каталог
       ACTION=="remove", ENV{dir_name}=="?*", RUN+="/bin/rmdir /mnt/%E{dir_name}", GOTO="end"
       # проверяем на предмет монтирования
       ACTION=="add", PROGRAM=="/usr/bin/find /mnt/usbkey", RESULT=="/mnt/usbkey", GOTO="end"
       # ищем именно наши флэшки (просто у меня их две - с запасом, а посмотреть uuid можно /lib/udev/vol_id -u /dev/sdd1)
       # и переходим к монтированию, иначе уходим в конец
       ACTION=="add", PROGRAM=="/lib/udev/vol_id -u %N", RESULT=="4B7E-E254", GOTO="mount"
       ACTION=="add", PROGRAM=="/lib/udev/vol_id -u %N", RESULT=="2C3E-F663", GOTO="mount"
       GOTO="end"
       LABEL="mount"
       # опции монтирования и переменная каталога
       ACTION=="add", ENV{mount_options}="ro,utf8,noexec,nodev,noauto", ENV{dir_name}="usbkey"
       # создаем каталог
       ACTION=="add", RUN+="/bin/mkdir /mnt/%E{dir_name}"
       # монтируем ключ
       ACTION=="add", RUN+="/bin/mount -t vfat -o $env{mount_options} /dev/%k /mnt/%E{dir_name}"
       # открываем наш криптованный том
       ACTION=="add", RUN+="/sbin/cryptsetup --key-file /mnt/usbkey/public.key luksOpen /dev/md0 public"
       # монтируем его
       ACTION=="add", RUN+="/bin/mount /dev/mapper/public /public -t ext3 -o defaults"
       LABEL="end
    
    Отладку конфигурации можно сделать так:
    
       udevcontrol log_priority=9999
    
    И смотреть журнал:
    
       tail -f /var/log/messages
    
    В итоге, получим динамически монтируемые тома на основе usbtoken'ов.
    
     
    ----* Доступ к шифрованному файлу паролей (доп. ссылка 1)   Автор: Вячеслав  [комментарии]
     
    В моей сети есть много устройств и служб, доступ к которым осуществляется
    посредством telnet. Обычно, устройства группируются по типу и зачастую имеют
    разные пароли. Запомнить десяток паролей, помимо личных, не всегда легко.
    Привычно хранить пароли внутри шифрованного раздела, хранилища TrueCrypt или
    шифрованного с помощью GPG файла. А пользователям Windows со своей SecureCRT,
    вообще, об этом думать не надо.
    
    Тем не менее использовать SecureCRT можно и в Linux. В моем случае
    (используется шифрованный GPG-файл) неудобство появляется в тот момент, когда
    нужно скопировать пароль в буфер обмена: приходится переключаться с клавиатуры
    на мышь. Это неудобно + если за вашей спиной стоит инженер из другой службы, не
    всегда нужно, чтобы он видел ваши пароли. Выход найден в использовании утилиты xclip.
    
    Но до удобного использования xclip нужно сделать дополнительные манипуляции с
    файлом .bash_aliases. Я дописал в свой .bash_aliases следующее:
    
       # TrueCrypt
       secret ()
       {
           local KEY="$1"
           local FILE="<ПУТЬ К ФАЙЛУ С ПАРОЛЯМИ>"
           echo -ne `awk '/^'$KEY'/ {print $2;exit}' $FILE` | xclip
       }
    
       # GPG
       secret_gpg ()
       {
           local KEY="$1"
           local FILE="<ПУТЬ К ШИФРОВАННОМУ ФАЙЛУ С ПАРОЛЯМИ>"
           echo -ne `gpg -o - $FILE | awk '/^'$KEY'/ {print $2;exit}'` | xclip
       }
    
       alias @="secret_gpg"
    
    Немного о формате файла с паролями. Файл состоит из строк, содержащих ключ и
    текст для копирования в буфер обмена, разделенных пробелами. Например:
    
       cisco true\nDFDFDGDF\n
       dlinka admin\nEEEEEEE\n
       dlinkt technical\nDDDDDD\n
    
    Я использую GPG, поэтому написал алиас для @ как secret_gpg. Вы можете
    использовать secret. Теперь можно делать так:
    
       true@hamster:~$ @ cisco
       true@hamster:~$ telnet router1
    
    
    Разумеется, в последнем примере пароль был не введен вручную, а просто вставлен
    из буфера обмена (в gnome-terminal с помощью Shift+Ins).
    
     
    ----* Хранение конфиденциальных данных в DropBox (доп. ссылка 1)   Автор: silverghost  [обсудить]
     
    Для организации безопасного хранения и синхронизации приватных данных данных при помощи сервиса
    DropBox (http://getdropbox.com) можно задействовать функцию шифрования каталогов. 
    Рекомендации подойдут и для сервиса Ubuntu One (http://one.ubuntu.com)
    
    Ставим DropBox-клиента c https://www.getdropbox.com
    
    После чего в каталог ~/Dropbox переносим все необходимые нам каталоги.
    Например, Документы, Картинки, Рабочий стол.
    
    Если перенесли системные каталоги (перечисленные выше), то на их месте делаем символические ссылки.
    
       ln ~/Dropbox/Документы ~/Документы
       и т.п.
    
    Теперь приступим к шифрованию критически важных данных. Устанавливаем encfs:
    
       sudo apt-get install encfs
    
    и создаем шифрованный каталог:
    
       encfs ~/Документы/.crypt ~/Документы/Encrypted
    
    Таким образом, создаем шифрованный каталог .crypt и монтируем его в Encrypted. 
    В директорию Encrypted  переносим критически важные данные.
    
    В результате чего на серверы сервиса DropBox данные попадут в зашифрованном виде.
    
    На другом компьютере устанавливаем DropBox и encfs и монтируем так же каталоги. 
    В результате получаем постоянно синхронизированные данные на двух компьютерах
    (синхронизация производится в фоне,
    скорость записи данных как у обычной локальной директории).
    
     
    ----* Проверка SSL сертификата из командной строки (доп. ссылка 1)   [комментарии]
     
    Предположим, что нам нужно проверить SSL сертификат сайта www.test.net
    
    Создаем рабочие директории:
    
        mkdir -p ~/tmp/cert
        cd ~/tmp/cert
    
    1. Получаем копию сертификата:
    
       openssl s_client -showcerts -connect www.test.net:443 > test.pem
    
    
    Запоминаем данные из секции "Server certificate", касающиеся утвердившей сертификат организации:
    
       cat test.pem| grep issuer
    
       issuer=/C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, Inc./OU=http://certificates.godaddy.com/repository/CN=Go Daddy...
    
    Непосредственно нужный нам сертификат находится в test.pem между метками
    "-----BEGIN CERTIFICATE-----"
    и "-----END CERTIFICATE-----",  удалять лишнее не обязательно, утилиты openssl
    воспримут его и в таком виде.
    
    2. Получаем сертификат удостоверяющего центра, URL которого мы нашли на прошлом шаге в поле issuer:
    
       wget https://certs.godaddy.com/repository/gd_bundle.crt -O gd.pem
    
    3. Создаем символические ссылки на основе сопоставленных им хешей:
    
       c_rehash ~/tmp/cert
    
       Doing  ~/tmp/cert
       test.pem => 1d97af50.0
       gd.pem => 219d9499.0
    
    4. Проверка сертификата.
    
    Удостоверимся, что сертификаты рабочие и загружены корректно:
    
       openssl verify -CApath ~/tmp/cert/ 
    
    или для проверки текущего состояния сайта в сочетании с ранее сохраненными сертификатами:
    
       openssl s_client -CApath ~/tmp/cert/ -connect www.test.net:443 | grep "Verify return code:"
    
       Verify return code: 0 (ok)
    
     
    ----* Настройка работы шифрованного корневого раздела во FreeBSD (доп. ссылка 1)   [комментарии]
     
    Устанавливаем систему стандартным образом в один минимальный корневой раздел,
    для дополнительных разделов
    создаем фиктивные точки монтирования. Таблица разделов имеет примерно такой вид:
    
       ad4s1a / 256M
       ad4s1b swap
       ad4s1d /new-root
       ad4s1e /new-tmp
       ad4s1f /new-var
       ad4s1g /new-usr
    
    Загружаемся в установленную систему.
    
    В /boot/loader.conf добавляем 
    
       geom_eli_load="YES"
    
    Отмонтируем раздел /new-root, который будет содержать новый шифрованный корень:
    
       umount /new-root
    
    Инициализируем шифрование будущего корня и форматируем раздел:
    
       geli init -b -l 256 /dev/ad4s1d
       geli attach /dev/ad4s1d
       newfs -L root /dev/ad4s1d.eli
    
    В  /etc/fstab меняем /dev/ad4s1d на /dev/ad4s1d.eli
    Монтируем шифрованный раздел:
    
       mount /new-root
    
    Создаем ключи для шифрования остальных разделов, заполнив их случайными данными:
    
       dd if=/dev/random of=/new-root/ad4s1e.key bs=512 count=1
       dd if=/dev/random of=/new-root/ad4s1f.key bs=512 count=1
       dd if=/dev/random of=/new-root/ad4s1g.key bs=512 count=1
    
    Отключаем активный раздел подкачки и  шифруем его:
       swapoff -a
       geli onetime -l 256 -s 4096 /dev/ad4s1b
    
    В /etc/fstab меняем для раздела подкачки /dev/ad4s1b на /dev/ad4s1b.eli
    Активируем раздел подкачки:
       swapon -a
    
    Готовим шифрованные разделы tmp, var и usr:
    
       umount /new-tmp
       umount /new-var
       umount /new-usr
    
       geli init -K /new-root/ad4s1e.key -l 256 -P /dev/ad4s1e
       geli init -K /new-root/ad4s1f.key -l 256 -P /dev/ad4s1f
       geli init -K /new-root/ad4s1g.key -l 256 -P /dev/ad4s1g
       geli attach -k /new-root/ad4s1e.key -p /dev/ad4s1e  
       geli attach -k /new-root/ad4s1f.key -p /dev/ad4s1f
       geli attach -k /new-root/ad4s1g.key -p /dev/ad4s1g
    
       newfs -L tmp /dev/ad4s1e.eli
       newfs -L var /dev/ad4s1f.eli
       newfs -L usr /dev/ad4s1g.eli
    
    Формируем будущий образ иерархии монтирования разделов:
    
       cd /new-root
       mkdir tmp
       mkdir var
       mkdir usr
       mount /dev/ad4s1e.eli tmp/
       mount /dev/ad4s1f.eli var/
       mount /dev/ad4s1g.eli usr/
    
    Монтируем установочный диск с FreeBSD и копируем с него в новый корень образ базовой системы:
       mount /cdrom
       cd /cdrom/6.2-RELEASE/base
       cat base.?? | tar --unlink -xpzf - -C /new-root/
    
    Другой вариант скопировать уже установленный корень:
       
       tar -cf - / --exclude /new-root | tar -xf - -C /new-root
    
    Подготавливаем новый корень к загрузке:
    
       mkdir /new-root/mnt/boot
       cp /etc/fstab /new-root/etc/fstab
    
    В /new-root/etc/fstab добавляем разделы для монтирования:
    
        /dev/ad4s1a /mnt/boot ufs rw 1 1
        /dev/ad4s1e.eli / ufs rw 1 1
        /dev/ad4s1d.eli /tmp ufs rw 1 1
        /dev/ad4s1g.eli /usr ufs rw 1 1
        /dev/ad4s1f.eli /var ufs rw 1 1
     
    В /new-root/etc/rc.conf определяем монтирование дополнительных шифрованных разделов:
    
        geli_devices="ad4s1e ad4s1f ad4s1g"
        geli_ad4s1e_flags="-p -k /ad4s1e.key"
        geli_ad4s1f_flags="-p -k /ad4s1f.key"
        geli_ad4s1g_flags="-p -k /ad4s1g.key"
    
    Из старого корня делаем минимальный загрузочный раздел /mnt/boot, в  /etc/fstab оставляем:
    
        /dev/ad4s1d.eli / ufs rw 1 1
    
    Перезагружаемся, чистим содержимое /mnt/boot, оставив только /mnt/boot/boot/* и /mnt/boot/etc/fstab
    
     
    ----* Создание шифрованного загрузочного LiveUSB c Debian GNU/Linux (доп. ссылка 1)   [комментарии]
     
    Добавление Loop-AES шифрования к Debian Live.
    
    Устанавливаем пакет для создания livecd сборки debian (все операции проводятся
    под пользователем root):
    
       apt-get install live-helper
    
    Создаем директорию в которой будем производить сборку (на диске должно быть
    минимум 3 Гб свободного места):
    
       mkdir DebianLive
       cd DebianLive
    
    Определяем конфигурацию LiveCD:
    
       lh_config -b usb-hdd -d lenny -e aes256
    
    При необходимости правим параметры или удаляем/добавляем пакеты через правку
    настроек в созданной директории config/:
    Дополнительные пакеты можно поместить в config/chroot_local-packages/
    Список пакетов из стандартных репозиториев в config/chroot_local-packageslists/
    (готовый список в /usr/share/live-helper/lists/)
    Помещаемые на LiveUSB дополнительные файлы  можно скопировать в config/chroot_local_includes/,
    например для добавления /etc/privoxy/config, его нужно скопировать как config/chroot_local-includes/etc/privoxy/config
    
    
    Запускаем процесс сборки LiveCD:
    
       lh_build
    
    в процессе работы скрипт потребует два раза ввести пароль, под которым будет
    осуществляться доступ к содержимому LiveUSB.
    
    Далее копируем получившийся образ на usb flash /dev/sdc:
    
       dd if=binary.img of=/dev/sdc bs=1M
    
    Шифрование используется для безопасного хранения на LiveUSB таких данных как
    PGP ключи, сохранные в firefox ключи и пароли.
    
    Некоторые полезные опции lh_config:
    -d lenny  - имя релиза (lenny|squeeze|sid)
    -b usb-hdd  - тип итогового образа (iso|net|tar|usb-hdd)
    -e aes256   - тип шифрования (aes128|aes192|aes256)
    --mirror-bootstrap http://192.168.100.1:3142/ftp.de.debian.org/mirror/debian/
    --mirror-chroot http://192.168.100.1:3142/ftp.de.debian.org/mirror/debian/ 
    --mirror-chroot-security http://192.168.100.1:3142/security.debian.org/ 
         перенаправление к локальному apt-proxy
    --debian-installer enabled  - добавить инсталлятор Debian в Live-образ
    --debian-installer-distribution lenny  - выбор дистрибутива для инсталлятора (lenny|squeeze|sid)
    --packages-lists "my_package_list" установить пакеты определенные в config/chroot_locale-packageslist/my_package_list
    --bootstrap-flavour minimal --packages-lists "minimal"  - формирование
    минимального образа, размером около 100 Мб
    
     
    ----* Добавление SSL шифрования для не SSL сайта силами nginx (доп. ссылка 1)   [комментарии]
     
    Ниже представлен пример настройки SSL-акселератора, выполненного средствами http-сервера nginx.
    
    Предположим, что нужно проксировать сайт testhost.ru, размещенный на сервере 192.168.1.1.
    Следующий блок конфигурации определяет работу SSL-акселератора:
    
        server {
             listen 192.168.1.1:443;
             server_name testhost.ru;
             access_log logs/ssl.log main;
    
             ssl on;
             ssl_certificate /certs/ssl.crt;
             ssl_certificate_key /keys/ssl.key;
            
             location / {
               proxy_set_header X-Real-IP $remote_addr;
               proxy_set_header X-Forwarded-For $p roxy_add_x_forwarded_for;
               proxy_set_header Host $http_host;
               proxy_set_header X-FORWARDED_PROTO https;
               proxy_redirect false;
               proxy_pass http://main_site;
            }
        }
    
    В http секции конфигурации определяем сервер который будем проксировать:
    
       upstream main_site {
         server 192.168.1.1:8080;
       }
    
    При желании можно ограничить разрешенный тип шифрования:
    
       ssl_ciphers HIGH:!ADH;
       ssl_perfer_server_ciphers on;
       ssl_protocols SSLv3;
    
    
    Также можно  включить gzip сжатие проксируемого трафика, для этого в 
    http секции добавляем:
    
       gzip on;
       gzip_min_length 1100;
       gzip_buffers 4 8k;
       gzip_types text/plain text/html text/css text/js;
    
     
    ----* Создание шифрованного раздела в Linux (доп. ссылка 1)   [комментарии]
     
    В  CentOS 5.3 добавлена возможность создания шифрованных дисковых разделов на этапе установки.
    Рассмотрим ручное создание шифрованного раздела /dev/sdb3 при помощи dm-crypt/LUKS.
    
    Сryptsetup можно найти в пакете cryptsetup в репозиториях Debian, Ubuntu, SuSE, Fedora и CentOS:
    
    Установка: 
    
       apt-get install cryptsetup
    или
       yum install cryptsetup
    
    Заполняем раздел случайными данными, для удаления остаточной информации:
    
       dd if=/dev/urandom of=/dev/sdb3
    
    Инициализируем шифрованный раздел
    
       cryptsetup luksFormat /dev/sdb3
    
    в ответ на приглашение "Enter LUKS passphrase:" вводим пароль, под которым
    будет производиться доступ к созданному разделу.
    
    Проверяем все ли нормально было создано:
    
       cryptsetup isLuks /dev/sdb3 && echo Sucess
       Sucсess
    
    Смотрим параметры созданного раздела:
    
       cryptsetup luksDump /dev/sdb3
    
       LUKS header information for /dev/sdb3
       Version:        1
       Ciper name:    aes
       Cipher mode:    cbc-essiv:sha256
       Hash spec:      sha1
       ...
    
    Получаем UUID идентификатор раздела для его последующего монтирования без
    привязки к имени устройства:
    
       cryptsetup luksUUID /dev/sdb3
       d77eb752-8a90-4d94-ae9f-2bec0a22c5d3
    
    Подключаем шифрованный раздел, для его последующего монтирования:
    
       cryptsetup luksOpen /dev/sdb3 db
    
       Enter LUKS passphrase: вводим пароль
       key slot 0 unlocked.
       Command successful.
    
    Смотрим параметры расшифрованного устройства /dev/mapper/db, пригодного для монтирования:
    
       dmsetup info db
    
       Name:              db
       State:             ACTIVE
       Read Ahead:        256
       Tables present:    LIVE
       Open count:        0
       Event number:      0
       Major, minor:      253, 1
       Number of targets: 1
    
    Форматируем новый раздел:
    
       mke2fs -j /dev/mapper/db
    
    Создаем точку монтирования:
    
       mkdir /db
    
    Монтируем:
    
       mount /dev/mapper/db /db
    
    Добавляем настройки в /etc/crypttab в последовательности соответствующей
    порядку монтирования разделов:
    
       luks-d77eb752-8a90-4d94-ae9f-2bec0a22c5d3 UUID=d77eb752-8a90-4d94-ae9f-2bec0a22c5d3 none
    
    Добавляем автомонтирование в /etc/fstab (на этапе загрузки нужно будет вводить пароль):
    
       /dev/mapper/luks-d77eb752-8a90-4d94-ae9f-2bec0a22c5d3 /db ext3  defaults 0 0
    
    Для автомонтирования шифрованного раздела должен быть активен системный сервис /etc/init.d/crytdisks
    
    Для отключения раздела нужно использовать:
    
       umount /db
       crytsetup luksClose /dev/mapper/db
    
    Вместо ввода пароля можно сохранить ключ шифрования на USB брелок,
    последовательность примерно такая:
    
    Создаем ключ на flash:
       dd if=/dev/random of=/media/flash/pass.key bs=1 count=256
    
    Инициализируем раздел:
       cryptsetup luksFormat /dev/sdb3 /media/flash/pass.key 
    
    Подключаем раздел:
       cryptsetup --key-file /media/flash/pass.key luksOpen /dev/sdb3 db
    
    В /etc/crypttab вместо "none" добавляем путь к файлу с ключом.
    
     
    ----* Шифрование и просмотр видео (gpg, mplayer)   Автор: borey  [комментарии]
     
    Озадачился такой проблемой.
    Есть несколько видео клипов, которые я бы не хотел чтобы кто нибудь смог увидеть, 
    если украдут или взломают носитель. Частное видео. Но хотелось бы иметь удобный
    способ быстро его просмотреть.
    
    Для себя решил эту задачу просто. Шифровать gpg, а просматривать mplayer ом
    через специальный скрипт.
    
    1. Шифруем симметричным шифром
    
       gpg -c file.avi
    
    2. Для проигрывания используем такой простенький скрипт:
    
       #!/bin/sh
    
       echo  "Enter pass and press <Enter>:"
       stty -echo 
       read pass
       stty echo
    
       for i in $@ ;do
           echo "playing $i ..."
           echo $pass | gpg -d --passphrase-fd 0  "$i" | mplayer - >/dev/null 2>&1
    
       done
    
    Со скриптом конечно возможны варианты. Но меня вообщем устраивает.
    Единственный минус, при таком воспроизведении mplayer скроллить не может (raw режим).
    Если кому то это существенно , надо распаковывать во временный файл. Но так
    проигрываем в безопасности.
    Вообщем мои потребности такое решение удовлетворяет, надеюсь будет кому-то полезно.
    
     
    ----* Создание приватной шифрованной директории в Ubuntu 8.10 (доп. ссылка 1)   [комментарии]
     
    В Ubuntu 8.10 появилась возможность создания в домашней директории пользователя каталога, 
    для хранения приватных данных, хранимых в зашифрованном виде (для шифрования
    используется eCryptfs).
    
    Для включения данной возможности нужно установить пакет ecryptfs-utils:
    
       sudo aptitude install ecryptfs-utils
    
    Создаем директорию для помещения шифрованных данных:
    
       mkdir ~/Private
       chmod 700 ~/Private
    
    Монтируем ecryptfs (http://launchpad.net/ecryptfs) к созданной директории 
    (другой вариант запустить скрипт ecryptfs-setup-private, но он светит открытым
    пароль в списке процессов):
    
        sudo mount -t ecryptfs ~/Private ~/Private
    
    На появившееся приглашение набираем "1" (passphrase) и вводим пароль, который будет использован 
    для доступа к зашифрованной директории. Шифр выбираем по умолчанию (aes/16).
    Режим "passthrough" позволит отображать файлы, записанные в директорию при
    отключении шифрования (до монтирования).
    
    Отмонтируем директорию:
    
       sudo umount ~/Private
    
    Создаем в GNOME ярлык для быстрого монтирования. Жмем на десктопе правой
    кнопкой мыши и выбираем "Create Launcher"/"Создать ярлык".
    
    В параметрах добавляем:
    
        Type: Application in Terminal
        Name: Mount Private Folder
        Command: sudo mount -t ecryptfs ~/Private ~/Private -o
           key=passphrase,ecryptfs_cipher=aes,ecryptfs_key_bytes=16,ecryptfs_passthrough=n  
    
    При этом система в интерактивном режиме перед монтированием запросит пароль для
    расшифровки раздела.
    Вместо "~" нужно прописать полный путь к домашней директории.
    
    Через опцию passphrase_passwd_file можно указать путь к файлу в который
    сохранен пароль (например, его можно положить на Flash).
    Но в этом случае лучше вместо режима passphrase использовать openssl, оперируя
    SSL ключом, а не паролем.
    
    Используя PAM модуль pam_ecryptfs.so можно автоматизировать подключение шифрованного 
    раздела при вхоже в систему, используя стандартный системный пароль в качестве
    ключа для шифрования.
    В /etc/pam.d/common-auth добавляем после pam_unix.so :
    
       auth required pam_ecryptfs.so unwrap
    
    В /etc/pam.d/common-session:
    
       session optional pam_ecryptfs.so unwrap
    
    Для автоматизации настроек и установки можно использовать скрипт ecryptfs-setup-pam.sh
    
     
    ----* Как вытащить из SSL сервиса серверный сертификат (доп. ссылка 1)   Автор: Александр Герасёв  [комментарии]
     
    Команда для того, чтобы вытащить из ssl-enabled сервиса серверный сертификат:
    
       openssl s_client -connect server:port -showcerts
    
     
    ----* Как зашифровать файл используя mcrypt или openssl (доп. ссылка 1)   Автор: nixcraft  [комментарии]
     
    mcrypt (http://mcrypt.sourceforge.net)
    
    Зашифровать:
       mcrypt data.txt
          Enter passphrase:
    Расшифровать:
       mcrypt -d data.txt.nc
          Enter passphrase:
    
    openssl (http://www.openssl.org)
    
    Зашифровать:
       openssl enc -aes-256-cbc -salt -in file.txt -out file.out
          Enter aes-256-cbc encryption password:
    Расшифровать:
       openssl enc -d -aes-256-cbc -in file.out
          Enter aes-256-cbc encryption password:
    
     
    ----* Шифрованный виртуальный диск под FreeBSD 5 (доп. ссылка 1)   Автор: levsha  [комментарии]
     
    Предполагается что в полном распоряжении есть FreeBSD 5.X
    Разборки "что ставить на сервер: 4.X или 5.X" не обсуждаются.
    В случае использования FreeBSD 4.X необходимо вместо mdconfig использовать vnconfig
    и вместо gbde использовать vncrypt.
    
    Компилируем ядро с 
    
       options GEOM_BDE # поддержка шифрованых дисков
       device          md              # Memory "disks"
    
    Создаем директорию, где все будет валяться
    
       mkdir /usr/cert/
    
    Создаем файл, где будет файловая система (размером 100 мегабайт)
    
       dd if=/dev/zero of=fimage bs=1m count=100
    
    создаем девайс на основании этого файла и создем там таблицу разделов на весь диск
    
       mdconfig -a -t vnode -f /usr/cert/fimage -u 0
       disklabel -r -w md0 auto
    
    Инициируем gbde патишен
    
       gbde init /dev/md0c -i -L /usr/cert/fimage.lock
    
    В текстовом редакторе откроется конфиг файл для этого шифрованого раздела.
    Если используется UFS 1 или2 то рекомендуется изменить параметр sector_size с 512 на 2048.
    
    Сохраняемся, вводим два раза пароль, который будет использоваться для доступа к
    этому шифрованому разделу.
    
    Подключаем шифрованый раздел (будет запрошен пароль для подключения).
    
       gbde attach /dev/md0c -l /usr/cert/fimage.lock
    
    Создаем на полученном разделе файловую систему.
    
       newfs -U /dev/md0c.bde
    
    Создаем директорию, куда будем маунтить:
    
       mkdir /usr/cert/sslcert
    
    Монтируем
    
       mount /dev/md0c.bde /usr/cert/sslcert
    
    Типа все работает. Теперь создадим скрит для удобства
    монтирования/размонтирования с таким содержанием:
    
    #!/bin/sh
    
    case "$1" in
            start)
                    /sbin/mdconfig -a -t vnode -f /usr/cert/fimage -u 0
                    /sbin/gbde attach /dev/md0c -l /usr/cert/fimage.lock
                    /sbin/mount /dev/md0c.bde /usr/cert/sslcert
            ;;
            stop)
                    /sbin/umount /usr/cert/sslcert
                    /sbin/gbde detach /dev/md0c
                    /sbin/mdconfig -d -u 0
            ;;
            *)
                    echo ""
                    echo "Usage: `basename $0` { start | stop }"
                    echo ""
                    exit 64
            ;;
    esac
    
    
    Все, пользуемся в свое удовольствие.
    
    При подготовке использованы источники: FreeBSD Handbook , mdconfig(8), gbde(8)
    
     
    ----* Шифрованный swap в FreeBSD 6.0   Автор: neozoid  [комментарии]
     
    Добавить в /boot/loader.conf:
       geom_eli_load="YES"
    
    или в конфиг ядра:
       device crypto
       options GEOM_ELI
    
    в fstab к разделу swap к "Device" дописать ".eli" например:
       # Device                Mountpoint      FStype  Options         Dump    Pass#
       #/dev/ad0s3b            none            swap    sw              0       0
       /dev/ad0s3b.eli         none            swap    sw              0       0
    
    при загрузке имеем:
       GEOM_ELI: Device ad0s3b.eli created.
       GEOM_ELI:     Cipher: AES
       GEOM_ELI: Key length: 256
       GEOM_ELI:     Crypto: software
    
    и в моем случае:
       %pstat -s
       Device          1K-blocks     Used    Avail Capacity
       /dev/ad0s3b.eli   1048576        0  1048576     0%
    
     
    ----* Аутентификация без пароля через USB Flash в Linux (доп. ссылка 1)   [комментарии]
     
    Цель - организовать аутентификацию пользователя в Linux системе, не через ввод пароля, 
    а через вставку USB флэша или CDROM, содержащего DSA ключ.
    
    1. Устанавливаем  pam_usb (http://pamusb.sourceforge.net/);
    
    2. В /etc/pam.d/login, /etc/pam.d/xdm и т.д. прописываем, в зависимости от режима:
       2.1. Вход только при вставке Flash с ключем:
          auth       required        pam_usb.so
          #auth required pam_unix.so # комментируем строку.
    
       2.2. Можем войти просто вставив Flash или набрав пароль:
          auth       sufficient      pam_usb.so # ставим перед "auth required pam_unix.so"
    
       2.3. Режим входа только при вставке Flash с ключем одновременно с вводом пароля:
          auth       required        pam_usb.so # ставим перед "auth required pam_unix.so"
    
    3. Монтируем Flash в /mnt/usb и генерируем для пользователя ключ:
       usbadm keygen /mnt/usb логин 1024
    
     
    ----* popa3d + TLS/SSL (stunnel) на FreeBSD 5.4   Автор: Вотинцев Сергей А.  [комментарии]
     
    Установка stunnel:
    
       cd /usr/ports/security/stunnel
       make && make install (!) не торопимся делать clean
       Копируем из папки work в /usr/local/etc/stunnel - stunnel.cnf, затем делаем make clean.
    
    Создаем сертификат:
       cd /usr/local/etc/stunnel && openssl req -new -x509 -days 365 \
          -nodes -config stunnel.cnf -out stunnel.pem -keyout stunnel.pem
       chmod 600 stunnel.pem && chown root:wheel stunnel.pem
    
    Конфиг для stunnel:
    
       cert = /usr/local/etc/stunnel/stunnel.pem
       RNDfile = /usr/local/etc/stunnel/stunnel.rnd
       chroot = /usr/local/var/stunnel/
       setuid = stunnel
       setgid = stunnel
       pid = /run/stunnel.pid
       output = /var/log/stunnel.log
       ciphers = HIGH
       debug = 6
       compression = rle
       [pop3s]
       accept  = 995
       connect = 127.0.0.1:110
    
    Делаем chroot:
    
       cd /usr/local/var && mkdir stunnel && cd stunnel
       mkdir etc && touch hosts.allow
       cd .. && mkdir run
    
    Содержание hosts.allow:
    
       pop3s : ALL : allow
       ALL : ALL : deny
    
    Права на директории /usr/local/var/stunnel
    
       drwxr-xr-x  2 root     wheel    512 Jul 30 20:31 etc
       drwxr-xr-x  2 stunnel  stunnel  512 Aug  3 15:55 run
    
    Правим rc.conf, если у Вас запускается только popa3d из inetd:
    
       inetd_flags="-wWa 127.0.0.1"
       /usr/local/etc/rc.d/stunnel.sh start
    
    Просмотр ciphers:
    
       openssl ciphers -v 'HIGH'
    
     
    ----* Защищенный канал связи используя stunnel   Автор: Wely  [комментарии]
     
    Мне потребовалось сделать защищённый канал для связи, под FreeBSD 5.4. 
    Выбрал самый легкий путь для моих условий: поставить stunnel. 
    Эта программа занимается перенаправлением портов через ssl-канал к обычным портам. итак:
    
    1) portupgrade -fN stunnel
    
    2) такой скрипт для создания самоподписанного ssl сертификата:
    
       !/bin/sh
       openssl genrsa -des3 -out ca.key 1024
       openssl req -new -x509 -days 365 -key ca.key -out ca.crt
       openssl req -new -nodes -out req.pem -keyout cert.pem
       chmod 600 cert.pem
       chown root:0 cert.pem
       openssl x509 -req -CA ca.crt -CAkey ca.key -days 365 -in req.pem -out signed-req.pem -CAcreateserial
       cat signed-req.pem >> cert.pem
       echo Сертификат готов в файле : cert.pem
    
    3) копируем cert.pem в /usr/local/etc/stunnel
    
    4) правим /usr/local/etc/stunnel/stunnel.conf
    
    5) запускаем stunnel и коннектимся к адресу:порту
    
     
    ----* Шифрованная передача текста (openssl+nc)   Автор: ZEDER  [обсудить]
     
    Передаём на хост .1 в порт 666 текст предварительно его зашифровав паролем "paSSw0rd":
       echo ТЕКСТ | openssl des3 -salt -k paSSw0rd | nc 192.168.48.1 666
    
    принимаем на порту 666 текст:
       nc -l -p 666 | openssl des3 -d -k paSSw0rd
    
     
    ----* Шифрование файлов используя loopback устройство под Debian Linux (доп. ссылка 1)   [комментарии]
     
    Установка пакетов:
        apt-get install loop-aes-utils
        apt-get install cryptsetup
    
    Подгрузка модулей:
       modprobe loop
       modprobe aes
    
    Создаем образ будущего шифрованного раздела:
        dd if=/dev/zero of=/home/marco/crloop bs=1M count=640
    
    Способ 1 (устарел, лучше использовать dm-crypt):
        modprobe cryptoloop
        losetup -e aes /dev/loop0 /home/marco/crloop
        mkfs -t ext2 /dev/loop0
        mount /dev/loop0 /media/cryptovolume
        .....
        umount /media/cryptovolume
        losetup -d /dev/loop0
    
    Способ 2 (рекомендуется для новых ядер):
        modprobe dm-crypt
        losetup /dev/loop0 /home/marco/crloop
        cryptsetup -c aes -y create crloop /dev/loop0
        mkfs.ext3 /dev/mapper/crloop
        mount /dev/mapper/crloop /media/cryptovolume
        .....
        umount /media/cryptovolume
        cryptsetup remove crloop
        losetup -d /dev/loop0.
    
     
    ----* Генерация сертификатов для mod_ssl (доп. ссылка 1)   Автор: Александр Елисеенко  [комментарии]
     
    В состав дистрибутива openssl входят скрипты CA.sh и CA.pl (/usr/local/openssl/misc)
    создаем корневой сертификат
    	./CA.sh -newca
    генерируем личный ключ и сертификационный запрос сервера
    	./CA.sh -newreq
    и подписываем его своим корневым сертификатом.
    	./CA.sh -sign
    переписываем ключ и сертификат сервера в служебный каталог Apache
    	cp newreq.pem   /usr/local/etc/apache/sslkey/server.key
    	cp newcert.pem  /usr/local/etc/apache/ssl.crt/server.crt
    Файл корневого сертификата ./demoCA/cacert.pem необходимо 
    распространить по клиентским компьютерам.
    
     
    ----* Симметричное шифрование блока данных на Perl.   [комментарии]
     
    use Crypt::Blowfish;
    use Crypt::CBC;
    my $cipher = new Crypt::CBC("Секретный ключ для шифрования",'Blowfish');
    my $crypted_block = $cipher->encrypt_hex($text);
    my $text = $cipher->decrypt_hex($crypted_block);
    $cipher->finish();
    
     
    ----* Как настроить работу шифрованной файловой системы в Linux (доп. ссылка 1)   [комментарии]
     
    1. Устанавливаем патчи cryptoapi и cryptoloop http://www.kernel.org/pub/linux/kernel/crypto/
    2. dd if=/dev/zero of=/usr/testfs bs=1M count=50
    3. modprobe cryptoloop; modprobe cryptoapi; modprobe cipher-des
    4. losetup -e des /dev/loop0 /usr/testfs
    5. mkfs -t ext3 /dev/loop0
    6. mount -t ext3 /dev/loop0 /mnt/testfs
    
     
    ----* Чем в perl лучше шифровать данные.   [обсудить]
     
    Необратимое шифрование (хэш или fingerprint):
      Модули (в порядке возрастания надежности) Digest::MD5, Digest::SHA1, Digest::HMAC_MD5, Digest::HMAC_SHA1
      Пример: use Digest::SHA1 qw(sha1_base64); 
              $hash = sha1_base64("test");
    
    Обратимое шифрование по ключу:
      Модули: Crypt::DES, Crypt::HCE_SHA, Crypt::Blowfish + Crypt::CBC
      Пример: use Crypt::Blowfish; use Crypt::CBC;
              $cipher_handle = new Crypt::CBC($encrypt_key,'Blowfish');
              $crypted_text = $cipher_handle->encrypt_hex($text);
              $text = $cipher_handle->decrypt_hex($crypted_text);
    
    Шифрование с использованием открытого ключа: Crypt::OpenPGP, Crypt::GPG , Crypt::PGP5.
    
     
    ----* Шифрование файла   [обсудить]
     
    pgp2.6>cat input| pgp -ef userid > output
    pgp5.0>cat input| pgpe -f userid > output
    gnupg>cat input| gpg -e -r userid > output
    
     
    ----* Расшифровка файла   [обсудить]
     
    pgp2.6>cat encrypted_файл | pgp -f -z'пароль' > расшифрованный_файл
    pgp5.0>cat encrypted_файл | pgpv -f -z'пароль' > расшифрованный_файл
    gnupg>cat encrypted_файл | gpg --decrypt > расшифрованный_файл
    
     
    ----* Добавление чужого публичного ключа   [обсудить]
     
    pgp2.6>pgp -ka <файл с ключом с удаленной машины>
    pgp5.0>pgpk -a <файл с ключом с удаленной машины>
    gnupg>gpg --import <файл куда будет записан ключ>
    # Для pgupg необходимо заверить ключ:
    gnupg>gpg --sign-key <имя ключа>
    
     
    ----* Экспортирование публичного ключа   [обсудить]
     
    pgp2.6> pgp -akx <UserID> <файл куда будет записан ключ>
    pgp5.0> pgpk -ax <UserID> <файл куда будет записан ключ>
    gnupg> gpg --export -a <UserID> > <файл куда будет записан ключ>
    
     
    ----* Cоздание публичного и секретного ключей   [обсудить]
     
    	pgp2.6> pgp -kg
    	pgp5.0> pgpk -g
    	gnupg> gpg --gen-key
    
     
    ----* Заметки по использованию GPG   [обсудить]
     
    --verify source-name.asc
    	Проверить по сигнатуре
    --gen-key
    	Сгенерировать новый PGP ключ (--quick-random - быстрая но не безопасная генерация)
    --gen-revoke uid
    	Сгенерировать сертификат на случай забытия пароля.
    -s file
    	Создать сигнатуру для файла (-sa - в .asc формате)
    -e -r user file
    	Зашифровать файл
    -se -r encuser -u siguser
    	Шифрование и подпись зашифрованного
    --export
    	Экспортировать публичные ключи
    --import file
    	Импортировать публичный ключ
    --edit-key user
    	Операции по редактированию keyring
    --batch
    	Автоматическая обработка, без интерактивных диалогов
    
     
    ----* Использование HTTPS-сертификатов для шифрования и подписи произвольных данных (доп. ссылка 1)   Автор: Dennis Yurichev  [комментарии]
     
    Созданные для HTTPS сертификаты вполне можно использовать для формирования
    цифровых подписей к произвольным данным, а также для шифрования по открытым ключам.
    
    Создание подписи.
    
    Имеем следующие файлы с сертификатами от Let's Encrypt:
    
       /etc/letsencrypt/live/site.com# ls -la
       ...
       lrwxrwxrwx  1 root root   42 May  22 8:11 cert.pem -> ../../archive/site.com-0001/cert43.pem
       lrwxrwxrwx  1 root root   43 May  22 8:11 chain.pem -> ../../archive/site.com-0001/chain43.pem
       lrwxrwxrwx  1 root root   47 May  22 8:11 fullchain.pem -> ../../archive/site.com-0001/fullchain43.pem
       lrwxrwxrwx  1 root root   45 May  22 8:11 privkey.pem -> ../../archive/site.com-0001/privkey43.pem
       ...
    
    Для заверения цифровой подписью файла msg.txt можно использовать закрытый ключ
    из файла privkey.pem:
    
       openssl dgst -sha256 -sign privkey.pem -out msg.txt.sig msg.txt
    
    После чего полученную подпись можно преобразовать в текстовое представление в кодировке Base64:
    
       openssl base64 -in msg.txt.sig -out msg.txt.sig.asc
    
    
    Далее можно опубликовать файлы msg.txt и msg.txt.sig.asc, а сторонние
    пользователи могут воспользоваться открытым ключом от домена site.com для
    верификации неизменности содержимого msg.txt:
    
    Загружаем открытый ключ сайта site.com  в файл pubkey.pem:
    
       openssl s_client -connect site.com:443 -showcerts | openssl x509 -pubkey -noout > pubkey.pem
    
    Преобразуем цифровую подпись в бинарный формат и верифицируем открытым ключом:
    
       openssl base64 -d -in msg.txt.sig.asc -out msg.txt.sig
       openssl dgst -keyform pem -verify pubkey.pem -signature msg.txt.sig msg.txt
    
       Verified OK
    
    
    
    Шифрование
    
    Сторонний пользователь может воспользоваться открытым ключом от домена site.com
    для шифрования данных, которые следует передать владельцу домена site.com,
    имеющему доступ к закрытому ключу.
    
       openssl pkeyutl -in msg.txt -out msg.enc -pubin -inkey pubkey.pem -encrypt
    
    Преобразуем зашифрованный бинарный файл в текстовое представление для передачи
    по электронной почте или через мессенджер:
    
       openssl base64 -in msg.enc -out msg.enc.asc
    
    
    Владелец закрытого ключа может расшифровать сообщение используя команды:
    
       openssl base64 -d -in msg.enc.asc -out msg.enc
       openssl pkeyutl -in msg.enc -out msg.txt -inkey privkey.pem -decrypt
    
     
    ----* Шифрование архива данных используя openssl   Автор: zeder  [комментарии]
     
    Шифрование:
    
       dd if=./target.tgz | openssl des3 -salt -kfile ./key.file| dd of=./target.tgz.des3
    
    Расшифровка:
    
       dd if=./target.tgz.des3 | openssl des3 -d -kfile ./key.file| dd of=./target.tgz
    
     

     Версия для печати





    Партнёры:
    PostgresPro
    Inferno Solutions
    Hosting by Hoster.ru
    Хостинг:

    Закладки на сайте
    Проследить за страницей
    Created 1996-2024 by Maxim Chirkov
    Добавить, Поддержать, Вебмастеру