Отключение обновлений Windows 10

Беда современных ОС от MS в том, что они считают себя умнее пользователя и обновляются когда это совсем не вовремя. И дело не только в том, что обновления не всегда полезны, а прежде всего это прерывает рабочий процесс. Оставил ПК на ночь с запущенными задачами, а он за ночь взял и сам перезагрузился. И на утро НИЧЕГО не осталось.

Поэтому отключаем. Отключить получается только обходными методами, в частности мы отключим задания из Планировщика. Просто так это сделать тоже не получится, даже запустив Планировщик из под администратора, не хватает прав.

Идём более длинным путём. Качаем PsExec, распаковываем и запускаем через cmd с правами администратора. Далее запускаем Планировщик:

psexec -i -s "C:\Windows\system32\mmc.exe" "C:\Windows\system32\taskschd.msc" /s

Далее отключаем неугодные задания из Microsoft\Windows\UpdateOrchestrator.

Всё. С внезапными обновлениями и перезагрузками покончено.

Обновление с небезопасного репозитария

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

Отмычка такая. Добавляем кастомный конфиг /etc/apt/apt.conf.d/99custom такого содержания:

Acquire::Check-Valid-Until "false";
Acquire::AllowInsecureRepositories "true";
Acquire::AllowDowngradeToInsecureRepositories "true";

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

Обновление с репозитария без подписи

Начиная примерно с дистрибутива buster стандартный установщик дебиана apt-get требует подписи всех используемых репозитариев. Обычный способ использования репозитария — добавление его подписи в систему. Это, однако, не всегда удобно и целесообразно. Иногда нужно что-то взять из сторонних репозитариев не добавляя подписи в систему. Это можно сделать разово при обновлении с помощью опции

apt-get update --allow-unauthenticated

Намного удобнее сделать это навсегда в отдельном списке репозитариев по типу:

deb [arch=amd64 allow-insecure=yes] http://www.deb-something-exampe.org buster main

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

UPD: Обновленный и более хороший способ

Отключение аутентификации Nginx для заданных ip-диапазонов

Удобный инструмент для защиты разного рода тестовых/разработческих сайтов — аутентификация на уровне веб-сервера по паролю. Она закрывает сайты от ненамеренного индексирования поисковиками и от входа третьих лиц. В Nginx такая делается директивой auth_basic, которая дополняется файлом с пользователями и паролями. Кто-то из разработчиков заходит со статических адресов, поэтому в им аутентификация не нужна и её можно отключить. Делается это следующим образом:

satisfy  any;
allow XX.XX.XX.XX/ZZ;
allow YY.YY.YY.YY/WW;
allow ...
deny   all;

auth_basic            "restricted area";
auth_basic_user_file  htpasswd/example.com;

Таким образом пользователи со статических адресов могут заходить на сайт без ввода паролей. Таким же образом можно открыть сайт для интернет-тестеров разных возможностей сайта, в частности оптимизации (google pagespeed, gtmetrix), безопасности и т.п.

Отключение телеметрии в Windows 10

Наконец-то нашёл хорошую и вменяемую утилиту для отключения телеметрии, шпионства и сбора данных в Windows 10. Работает также в версиях 7 и 8.x и поддерживается автором. Из решающего задачу приватности в windows аналогичного софта, эта утилита одна из лучших.

Удаляем в postfix лишние заголовки

Postfix — отличное типовое решение для корпоративного почтового сервера. Относительно легко ставится, хорошо интегрируется, доступно много всяких фич … что ещё нужно?

Безопасность. Если не конфигурировать явно, то postfix пропускает все заголовки, добавленные до него. Это могут быть:

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

    Received: from [192.168.0.116] (broadband-xxx-xxx-xxx-xx.example.com [xxx.xxx.xxx.xxx])
    by srv.example.com (Postfix) with ESMTPSA id 7AE4D122165
    for ; Sun, 8 Jan 2017 19:13:57 +0000 (UTC)

    Таким образом раскрывается внутренняя структура сети, а если есть ещё и внутренний релей и он добавляет свои заголовки — то и он тоже попадает в заголовки. Ясно дело, что это нежелательно.
    Хорошее решение: срезать все заголовки Received из письма на конечном отправляющем сервере.
    Отдельно замечу, что некоторые из публичных почтовых сервисов тоже светят адрес отославшего письмо, что не всегда хорошо для его безопасности. Вообще, это отдельная тема, что лучше выбрать.

  2. Сообщения, раскрывающию внутреннюю стуктуру почтовика, если в связки используются антивирус/антиспам и подобные решения. Тогда появляется localhost:

    Received: from localhost (localhost [127.0.0.1])
    by srv.example.com (Postfix) with ESMTP id 6466E12216D
    for ; Sun, 8 Jan 2017 19:47:46 +0000 (UTC)

  3. Полезной информации это не несёт, а значит лучше это и не дописывать в каждое сообщение.

  4. User-Agent (почтовый клиент) пользователя:

    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101
    Thunderbird/45.6.0

    Эта информация вполне безопасна, однако и её лишний раз лучше не светить — по письмам от разных пользователей одного домена можно узнать, например, какие операционные системы предпочитают в компании. Или здесь может светиться веб-почта

    User-Agent: Roundcube Webmail/1.2.3

    и сразу открывается ещё одна потенциально опасная точка входа.

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

    Received: by srv.example.com (Postfix, from userid 33)
    id 51C4212216F; Sun, 8 Jan 2017 20:07:31 +0000 (UTC)
    X-PHP-Originating-Script: 0:rcube.php

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

  6. Другие заголовки, которые я здесь не перечислил, но такие точно есть.

Далее →

Странности nginx ssl

Параметры SSL в конфигурации nginx могут быть описаны как в глобальной http-секции, так и в настройках локальных серверов server. В контексте server по логике настройки должны применяться только на этот сервер.

Интересно, что поддержка TLS v1.2 включается только если её включить в server-секциях всех виртуальных хостов, а не только нужного.

Парольная безопасность

Всем информационным безопасникам известны стандартные схемы повышения парольной безопасности. В частности, к таковым относятся:

  • Обязательная смена паролей по истечении определённого срока,
  • Автогенерация «бессмысленного» пароля с хорошим разнообразием символов и длиной, но который проблематично запомнить.

Эти новшества в последнее время вводят начиная от панелей хостинга, заканчивая интернет-банками. Я вижу всего два варианта, почему их вводят: чисто для бюрократии — что у нас есть парольный аудит и мы блюдём безопасность (с пониманием, что такая мера плохо работает) и когда инициатор действительно верит в то, что этим самым делает продукт безопаснее. Последнее в корне неверно.

А дело в том, что не будет пользователь, какой бы квалифицированный он не был, каждые 3 месяца получать «белибердовый» 12-значный пароль и запоминать его. А тётя Маша-бухгалтер и тем более не будет этого делать. Будут обходные пути и саботаж: пароль запишут на бумажку или ещё хуже — в файлик на компьютере. Причем, «тётя Маша» сделает это очевидным способом на самое видное место — рабочий стол, и ещё подпишет куда это вводить надо…

Понятно, что так не должно быть и это явное нарушение безопасности, но сама предложенная разработчиком схема прямо толкает на это нарушение — запоминать белиберду всё равно никто не будет.

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

Господа безопасники, если читаете это: применяйте схемы разумно. Давайте выбирать пароль пользователю самому, проверку на сложность и длину сделать — элементарная программисткая задача. Срок действия пароля тоже должен быть разумый. И обучайте пользователей: один долгий пароль в памяти намного лучше десятка сменных, но на бумажке или в файлике.

Вырезание заголовков в exim4

exim4 — отличный почтовый сервер для исходящей почты. По умолчанию он сохраняет заголовки полностью и добавляет ещё свои. В большинстве случаев эти заголвки делают письмо излишне информативным для получателя и этого желательно избежать.

Первое, что стоит сделать в типовой конфигурации сервера — скрыть внутреннюю структуру сети в отправляемых сообщениях, поскольку exim оставляет в заголовках оригинального отправителя. В типичном случае получатель увидит примерно следующее:

Received: from srv12 ([10.0.0.12])
	by mymail.example.com with esmtp (Exim 4.84)
	(envelope-from )
	id 1cPEo3-0003N7-Jj
	for user@example.com; Thu, 05 Jan 2013 20:38:39 +0000

или следующее

x-originating-ip: [10.54.14.36]

Как видим, почтовый сервер раскрывает адрес отправителя. Этим отправителем может быть сервер во внутренней сети или обычный пользователь с почтовым клиентом. В любом случае эта информация излишняя для получателя: адрес и имя самого почтового сервера в заголовках вполне достаточно. Почистить историю до почтовика можно срезав заголовки Received на этапе получаения почтовиком письма.

Если письмо генерируется автоматически, некоторые интерпретаторы по умолчанию добавляют информацию о себе и о запускаемом скрипте. В частности, этим отличается PHP:

X-PHP-Originating-Script: 0:myscript.php

Поэтому, также вырезаем заголовок X-PHP-Originating-Script.

Если же почтовый сервер обслуживает офис, то из заголовков можно узнать используемый почтовый клиент. Например,

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:45.0)
 Gecko/20100101 Thunderbird/45.5.1

или

X-Mailer: Microsoft Outlook 14.0

Обычно, эта информация вполне безопасна. Информацию о клиенте оставляют многие публичные почтовые сервисы. Однако, её тоже не всегда имеет смысл раскрывать. Особенно, если это веб-клиент или внутренняя CRM. Таким образом, можно ещё срезать заголовок User-Agent.

Существуют ещё много вариантов, в которых желательно отсечь излишне информативные заголовки. Замечательно, что в exim это сделать очень просто. Для этого необходимо в начале основной конфигурации сервера включить использоваие фильтра и указать файл конфигурации к нему

system_filter = /etc/exim4/filter

А в самом /etc/exim4/filter прописать вырезаемые заголовки. Например:

headers remove X-PHP-Originating-Script
headers remove Received

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

О правильном мониторинге

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

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

Минимум настроек apache2 и nginx веб-серверов для повышения безопасности

Рассмотрим типовую схему веб-сервера: nginx используется в качестве фронтэнда (front-end), apache2 — бэкэнда (back-end). Установка пакетов из репозитариев дает стандартную конфигурацию, которая применима для сервера разработки и тестирования. Однако, стоковая конфигурация изначально подстроена под большой класс задач и требует доработки. В частности, в плане безопасности. Опишем минимум настроек, которые необходимо сделать, если настраиваемый сервер выходит в интернет для широкого использования.

apache2

Отключаем потенциально опасные и просто неиспользуемые модули, а также неиспользуемые подконфиги. Почти всегда можно (и нужно) отключить:

  • модуль autoindex, позволяющий просматривать содержимое директории при отсутствии индексного файла,
  • обработку cgi-bin, которая в deb-based системах лежит в конфиге serve-cgi-bin.conf и используется очень редко,
  • Другие неиспользуемые модули (список которых зависит от выкладываемого кода). Т.е. необходимо перешерстить директории mods-enabled, conf-enabled

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

Apache/2.4.10 (Debian) Server at ...

Этот параметр, как и некоторые другие настройки безопасности в debian-системах обычно находится в конфиге /etc/apache2/conf-available/security.conf. Переключаем в менее информативную и, соответственно, более безопасную версию:

#ServerTokens Minimal
#ServerTokens OS
#ServerTokens Full
ServerTokens Prod

Аналогичным образом стоит поступить с подписью сервера на «ошибочных» страницах

ServerSignature Off
#ServerSignature On

и трассировкой

TraceEnable Off

Последняя обычно уже отключена, но в этом необходимо убедиться.

Код некоторых выкладываемых сайтов может содержать скрытые файлы, вроде .gitignore, .svn и других, раскрывающих стуктуру кода. Их желательно отключить здесь же, в апаче, или в фронт-энде. Можно отключить сразу все скрытые файлы:

<DirectoryMatch "/\.">
	Require all denied
</DirectoryMatch>

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

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

Отключим доступ к скрытым файлам — в секции виртуалхоста добавляем:

RedirectMatch 404 /\..*$

Такие файлы нередко встречаются в проектах. В частности, системы контроля версий вроде git, svn. Эта метаинформация не должна попадать в прошакш, тем не менее следует превентивно защититься от такой возможности.

Если VirtualHost на сервере не один, то также не плохо будет раскомментировать секцию


   AllowOverride None
   Order Deny,Allow
   Deny from all

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


	AllowOverride All
	Order Deny,Allow
	Allow from all

Я не описываю настройку прав доступа (пользователь:группа) на уровне ОС и файловой системы и использование модуля mpm_itk с директивой AssignUserID. Это тоже должно быть сделано для серверов, на которых такое разделение требуется.

nginx

Отключим отображение скрытых файлов:

location ~ /\. {
	deny all;
}

nginx используется как frontend, и если на нем отдается контент по https, то повышаем его безопасность. Для начала отключаем SSLv3 и другие небезопасные протоколы. Если nginx свежий, то в нем это уже и так отключено, поэтому лучше просто обновиться.
Генерируем параметры обмена ключами Diffie-Hellman (которые могут генерироваться достаточно долго, запаситесь временем)

openssl dhparam -out /etc/nginx/ssl/dhparam.pem 4096

и затем подключаем их в энжинксе

ssl_dhparam /etc/nginx/ssl/dhparam.pem;

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

ssl_ciphers 'AES256+EECDH:AES256+EDH:!aNULL';

Также имеет смысл включить кеширование

ssl_session_cache shared:SSL:10m;

После всех настроек желательно проверить их корректность в каком-нибудь сервисе, например, этом.

PHP

Как и в случае апача скрываем версию

expose_php = Off

В зависимости от задач можно отключить вывод ошибок:

error_reporting = 0
display_errors = Off

 

Проверки

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

HEAD example.com

Также побродим по сайту, в том числе по страницам, которые генерируют 4xx и 5xx ошибки, проверим, что версии софта не раскрываются и тем более не раскрывается внутренняя структура сервиса.

Завершающие замечания

Если на сервере хостится несколько сайтов, то многие из приведённых выше настроек повышают безопасность лишь частично. Сделать хорошую защиту между виртуалхостами на одной машине принципиально будет достаточно сложно. Если такое требуется — лучше смотреть в сторону виртуализации уровня операционной системы, по образцу OpenVZ или lxc.

Со временем пост будет пополняться.

Хорошие курсы по криптографии

Почти все MOOC при всех их преимуществах грешат одним недостатком — низкий уровень (что напрямую следует из требуемой для рекламы университетов популярности). Тем не менее, на курсере встречаются и действительно хорошие курсы. Например, по шифрованию:
Cryptography I
Cryptography II

Нельзя сказать, что это курсы продвинутого уровня, однако, они понятным языком покрывают обширные и весьма непростые разделы криптографии. Симметричное, несимметричное шифрование, хеши, MAC, HMAC, алгоритмы обмена ключами (Diffie-Hellman), введение в TLS/IPSec и многое другое. Причем, не только фактологически, но с объяснением внутренних связей, причин-следствий. Совмещение теории с практикой в хорошем смысле.
В общем, кто занимается Computer Security, Computer Science эти курсы будут полезны.

Защита от DDoS при помощи geoip

Основная задача любой оптимизации состоит в минимизации частоты исполнения медленного кода. Применительно к администрированию web-серверов, медленно генерируемые страницы должны запрашиваться нечасто, или такие страницы необходимо сделать быстро генерируемыми. Для многих «простых» сайтов на известных CMS и обвешанными плагинами любая страница генерируется с использованием значительных ресурсов. Это играет злую шутку на большой мусорной нагрузке, например при умном, но узким DDoS: даже такой сможет обвалить сайт.
В случае, если DDoS идёт из определённых стран, например из Китая и Индии (что происходит в большинстве случаев), то появляется быстрое и эффективное решение для защиты региональных сайтов — фильтр входящих запросов по географии и ответ только на запросы с нужных стран. Тогда, «вредные» запросы не доходят до backend, медленный код не исполняется и ресурсы серверы не тратятся, в результате чего сервер для локальных запросов сервер не падает и обычно даже работает с незаметным замедлением.

Делается это правилом вроде

$IPTABLES -A HTTP -m geoip ! --src-cc RU -j DROP

Перед этим правилом определяется стандартным образом цепочка HTTP (-p tcp --dport 80).

Способ, естественно, не годится на случай широких DDoS, нацеленных на заполнение канала (особенно udp-траффиком). Но для слабых, основанных на генерировании нагрузки, DDoS, он вполне годится.

PS: Естественно geiop модули к iptables должны быть поставлены заранее. Тогда этот способ будет действительно быстрым.

Резервные копии в Windows по сети

Используемые средства

К сожалению, Windows по сравнению с *nix-системами имеет очень слабый функционал для подготовки и копирования бэкапов. В последнее время имеется тенденция к улучшению (PowerShell), однако, полезных утилит все равно недостаточно. Обычные Windows-утилиты copy/xcopy очень плохо работают на большом количестве файлов. В интернете можно найти «продвинутую» версию xcopy под названием robocopy, именно её мы и будем использовать.

Полные бэкапы

Будем размещать резервные копии на сервере srv-bak. Копировать будем в сетевую шару \\srv-bak\bak\srv01, где srv01 — директория с именем сервера на бэкапном. Таким образом в одной директории будут храниться бэкапы с разных серверов.
На сервере с резервными копиями для каждой из них будем создавать директорию с текущей датой в качестве имени. Для удобства поместим исходные пути, которые нужно забэкапить, в файлик D:\backup\dirs.txt. Переносим всё это дело «на клавиатуру» и получаем такой скрипт:

set backupdir=\\srv-bak\bak\srv01
IF NOT EXIST %backupdir% (
	mkdir %backupdir%
)

set d=%date:~0,2%
set m=%date:~3,2%
set y=%date:~6,4%
set ndate=%y%%m%%d%

set dirsfile=D:\backup\dirs.txt

set dstpath=%backupdir%\%ndate%
IF NOT EXIST %dstpath% (
	mkdir %dstpath%
)

for /f "eol=; tokens=1 delims=" %%i in (%dirsfile%) do (
	mkdir "%dstpath%%%~pi%%~ni"
	robocopy "%%~di%%~pi%%~ni" "%dstpath%%%~pi%%~ni" /E /ZB /NP
)

Чтобы всё работало автоматически, добавляем скрипт в планировщик. Таким (простым!) способом можно бэкапить достаточно большие объемы. Единственный, но существенный, наблюдаемый баг — если какой-то из копируемых файлов занят, скрипт отработает некорректно.

Инкрементные/дифференциальные бэкапы

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

set backupdir=\\srv-bak\bak\srv01
IF NOT EXIST %backupdir% (
	mkdir %backupdir%
)

set d=%date:~0,2%
set m=%date:~3,2%
set y=%date:~6,4%
set ndate=%y%%m%%d%

if "%d%"=="01" (
	set dstpath=%backupdir%\%ndate%
) ELSE (
	set dstpath=%backupdir%\d%ndate%
)

IF NOT EXIST %dstpath% (
	mkdir %dstpath%
)

set /A prev=1%d%-100-1
if %prev% LSS 10 (
	set prev=0%prev%
)

set dirsfile=D:\backup\dirs.txt

if "%d%"=="01" (
	for /f "eol=; tokens=1 delims=" %%i in (%dirsfile%) do (
		:: xcopy "%%~di%%~pi%%~ni" "%dstpath%%%~pi%%~ni\" /C /E /H /Y
		mkdir "%dstpath%%%~pi%%~ni"
		robocopy "%%~di%%~pi%%~ni" "%dstpath%%%~pi%%~ni" /E /ZB /NP
	)
) ELSE (
	for /f "eol=; tokens=1 delims=" %%i in (%dirsfile%) do (
		:: xcopy "%%~di%%~pi%%~ni" "%dstpath%%%~pi%%~ni\" /D:%m%-%prev%-%y% /C /S /H /Y
		mkdir "%dstpath%%%~pi%%~ni"
		robocopy "%%~di%%~pi%%~ni" "%dstpath%%%~pi%%~ni" /MAXAGE:2 /S /ZB /NP
		rmdir "%dstpath%%%~pi%%~ni"
	)
)

IF EXIST %dstpath% (
	rmdir %dstpath%
)

Заключительные замечания

Вместо копирования по сети иногда бывает полезным разбиение этой задачи на 2 части: монтирование шары как локального диска и последующее копирование (и размонтирование по окончании). Приведённые скрипты несложным образом дорабатываются до такой версии.
Также, на принимающем сервере возможно организовать архивирование резервных копий. Если для сервера бэкапов используется Samba, то в шелле это элементарно делается периодическим выполнением в директории с бэкапами архивации вроде:

find -mindepth 2 -maxdepth 2 -type d -ctime +7 -execdir /usr/local/bin/tar_and_remove.sh "{}" \;

или

find -mindepth 2 -maxdepth 2 -type d -ctime +7 -execdir rar a -t -m5 -r -rr1 -df -inul "{}.rar" "{}" \; &> /dev/null

Кроме этого, с никсового сервера эти бэкапы очень удобно копировать с помощью ssh/scp/rsync.

Настройка виртуализации Windows под KVM libvirt linux

Система будет тестовая и стабильность на ней не нужна, поэтому настраивать это все будем в дистрибутиве Debian jessie, который на данный момент является веткой testing.
Оригинальные и краткие руководства к действию можно найти на дебиане: KVM и QEMU. Ниже несколько подогнанная под мои задачи выжимка.

Шаблон

Если потребуется создавать много виртуальных машин или менять их параметры, очень удобно создать шаблон конфигурации виртуальных машин и скрипт её создания. Можно, конечно создавать командами вроде

virt-install --connect qemu:///system \
--name vm1 \
--ram 1024 \
--vcpus=1 \
--disk pool=storage,cache=none,size=40, format= qcow2\
--disk /vm/Win7.iso,device=cdrom \
--bridge=br0,model=e1000 \
--os-type=windows
--graphics vnc,port=5911,listen=0.0.0.0

но делать это постоянно очень неудобно. В качестве шаблона создаем конфиг вроде

<domain type='kvm'>
  <name>{name}</name>
  <memory>{ram}</memory>
  <currentMemory>{ram}</currentMemory>
  <vcpu>1</vcpu>
  <os>
    <type arch='x86_64' machine='pc-0.12'>hvm</type>
    <boot dev='cdrom'/>
    <boot dev='hd'/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <pae/>
  </features>
  <clock offset='localtime'/>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>restart</on_crash>
  <devices>
    <emulator>/usr/bin/kvm</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='raw' cache='none'/>
      <source file='/vm/{name}.img'/>
      <target dev='vda' bus='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
    </disk>
    <disk type='file' device='disk'>
      <driver name='qemu' type='raw' cache='none'/>
      <source file='/vm/virtio.img'/>
      <target dev='hda' bus='ide'/>
      <address type='drive' controller='0' bus='0' unit='0'/>
    </disk>
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <source file='/vm/iso/ru_windows_8.1_professional_vl_with_update_x64_dvd_4050520.iso'/>
      <target dev='hdc' bus='ide'/>
      <readonly/>
      <address type='drive' controller='0' bus='1' unit='0'/>
    </disk>
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <source file='/vm/virtio-win-0.1-30.iso'/>
      <target dev='hdc' bus='ide'/>
      <readonly/>
      <address type='drive' controller='0' bus='1' unit='1'/>
    </disk>
    <controller type='ide' index='0'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
    </controller>
    <interface type='bridge'>
      <mac address='52:54:00:9d:be:d9'/>
      <source bridge='br0'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
    <serial type='pty'>
      <target port='0'/>
    </serial>
    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
    <input type='tablet' bus='usb'/>
    <input type='mouse' bus='ps2'/>
    <graphics type='vnc' port='{port}' autoport='no' listen='0.0.0.0' keymap='en-us' passwd='{passwd}'/>
    <video>
      <model type='vga' vram='9216' heads='1'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
    </video>
    <memballoon model='virtio'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
    </memballoon>
  </devices>
</domain>

Типовые шаблоны можно найти в документации, идущей вместе с пакетами. Также создаём устанавливающий скрипт vmcreate.sh:

#!/bin/sh

template=template.xml
path=/vm

while true; do
	read -p "VM name: " name
	if [ "$name" ]; then
		break
	fi
done


while true; do
	read -p "VNC port: " port
	case $port in
		[0-9]* ) break;;
	esac
done

while true; do
	read -p "VNC password: " password
	if [ "$password" ]; then
		break
	fi
done

while true; do
	read -p "HDD size in Gb [50]: " hdd
	case $hdd in
		[0-9]* ) break;;
		* )	hdd=50
			break;;
	esac
done

while true; do
	read -p "RAM in Mb [1536]: " ram
	case $ram in
		[0-9]* ) break;;
		* )	ram=1536
			break;;
	esac
done


echo "VM name: $name"
echo "VNC port: $port"
echo "Password: $password"
echo "HDD : $hdd Gb"
echo "RAM : $ram Mb"

while true; do
	read -p "Continue [y/N]? " yn
	case $yn in
		[Yy]* ) cont=1
			break;;
		* ) cont=0
			break;;
	esac
done

ramb=$((1024*$ram))

if [ -f "$path/$name.img" ]; then
#	cont=0
	echo "File $path/$name.img exist."
else
	qemu-img create -f raw "$path/$name.img" ${hdd}G
fi


if [ "$cont" -eq 1 ]; then
	sed "s/{name}/$name/g" $path/$template | sed "s/{port}/$port/g" | sed "s/{passwd}/$password/g" | sed "s/{hdd}/$hdd/g" | sed "s/{ram}/$ramb/g" > $path/$name.orig.xml
#	virsh create $name.orig.xml
	virsh define $name.orig.xml
	virsh start $name
else
	echo "Aborted."
fi

После такой подготовки виртуальная машина создается фактически запуском этого скрипта и ответом на вопросы. Конечную конфигурацию можно всегда поправить в XML-конфигах /etc/libvirt/qemu или с помощью утилиты virsh.

Типовая установка Windows в виртуалке

Драйвер от Win7 x64 вполне годится и для Windows 8.1, выбираем его при установке(Red Hat VirtIO SCSI controller, VIOSTOR.INF VirtIO Balloon Driver BALLOON.INF). Там же находим драйвер для сетевой карты, он пригодится позже. После этого виртуальный HDD находится системой, запускаем установку.
Уже на установленной системе ставим VirtIO-драйвер для Ethernet от Red Hat и настраиваем параметры сети.

Сеть

Для работы сети потребуется некоторая маршрутизация на самом хосте. Ниже представлен не самый оптимальный, но рабочий вариант для большинства (не-production) применений. А именно, разрешим forwarding на основной машине и явно пропишем пути из NAT-сети в интернет.
/etc/network/interfaces

up route add -host 10.0.5.2 dev br0

Также в местном фаерволле, т.е. скрипте, который настраивает iptables-правила, добавляем локальную сеть и нужные перенаправления:

IPTABLES=/sbin/iptables

echo 1 > /proc/sys/net/ipv4/ip_forward 2> /dev/null

ip addr add 10.0.6.1./24 dev br0
$IPTABLES -F -t nat
$IPTABLES -X -t nat

LAN="10.0.5.0/24"

$IPTABLES -A INPUT -s $LAN -j ACCEPT
$IPTABLES -A OUTPUT -s $LAN -j ACCEPT

$IPTABLES -t nat -A POSTROUTING -s $LAN -o br0 -j MASQUERADE

$IPTABLES -t nat -A PREROUTING -p tcp --dport 55003 -j DNAT --to-destination 10.0.5.3:3389

Управление с помощью утилиты virsh

Утилитой virsh совершаются штатно многие операции с вируалками. Наиболее часто используются старт, мягкая и жёсткая остановка

virsh start VMNAME
virsh shutdown VMNAME
virsh destroy VMNAME

Удалить существующую виртуальную машину (совсем!) также можно этой утилитой:

virsh undefine VMNAME

Как правило, виртуальная машина ставится надолго, поэтому её целесообразно стартовать при загрузке самой машины:

virsh autostart VMNAME

Завершающие дополнения

Конфиги виртуальных машин находятся в /etc/libvirt/qemu и могут быть исправлены до нужного состояния. В нём можно поменять физические параметры контейнера (объем ОЗУ, количество ядер и т.п.), также подключить/отключить образы жёстких дисков и CD/DVD.

На *nix-системах время обычно хранится в UTC, тогда как Windows его хранит в локальном часовом поясе. Проблему решает reg-файл следующего содержания:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation]
"RealTimeIsUniversal"=dword:00000001

LXC контейнеры в Debian jessie

LXC представляет собой набор утилит для управления виртуализацией на уровне операционной системы. Технология основана на механизме cgroups, которая позволяет создавать несколько Linux-окружений с собственным пространством процессов и сетевым стеком. Все контейнеры работают на одном ядре вместе с основной машиной, что делает виртуализацию этого типа очень эффективной. По этой причине виртуализация такого типа — отличный выбор для различных применений, где не требуется устанавливать дополнительные модули к ядру и подобная специфика.

Почти всю полезную информацию можно найти в дебиановском источнике. Ниже — наиболее короткий howto, как быстро настроить lxc-виртуализацию под Debian Linux.

Настройка хост-машины

Начинаем как обычно с установки необходимого софта

apt-get install lxc bridge-utils libvirt-bin debootstrap

Контейнеры будем создавать в стандартной директории /var/lib/lxc. Для удобства сделаем симлинк в корне файловой системы на эту директорию:

ln -s /var/lib/lxc

Настроим сеть. Для этого доустанавливается пакет bridge-utils, типовой конфиг сети (/etc/network/interfaces) будет следующим

auto lo
iface lo inet loopback

auto br0
iface br0 inet static
	address 123.123.123.3
	netmask 255.255.255.248
	gateway 123.123.123.1
	bridge_ports eth0
	bridge_fd 0
	bridge_maxwait 0
	bridge_stp off
	dns-nameservers 8.8.8.8 8.8.4.4

Проверяем, всё ли в порядке с установкой

lxc-checkconfig

и если все нормально, то ставим туда первый контейнер

lxc-create -n myvm -t debian

В результате получаем виртуальную машину и root-пароль к ней. Контейнер будет из stable-дистрибутива (Wheezy), однако его можно дообновить до testing или изначально ставить testing.

Настройка виртуальной машины

Конфиг виртуальной машины находится в /lxc/myvm/config. Доводим его до вменяемого состояния, например такого

lxc.network.type = veth
lxc.rootfs = /var/lib/lxc/myvm/rootfs

# Common configuration
lxc.include = /usr/share/lxc/config/debian.common.conf

# Container specific configuration
lxc.mount = /var/lib/lxc/myvm/fstab
lxc.utsname = myvm
lxc.arch = amd64


lxc.network.flags = up
lxc.network.link = br0

lxc.network.hwaddr = 00:25:90:01:5e:22

lxc.start.auto = 1

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

Перед запуском виртуалки также меняем сетевые настройки в /etc/network/interfaces.

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

apt-get install apt-utils iputils-ping cron rsyslog iptables

Иногда будем получать ругань вроде

perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
        LANGUAGE = (unset),
        LC_ALL = (unset),
        LC_CTYPE = "ru_RU.UTF-8",
        LC_COLLATE = "ru_RU.UTF-8",
        LC_MESSAGES = "C",
        LC_NUMERIC = "POSIX",
        LANG = (unset)
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_ALL to default locale: No such file or directory

Поэтому сразу конфигурируем локаль

dpkg-reconfigure locales

Стандартного почтового агента (MTA) в системе тоже нет, поэтому ставим его и настраиваем:

apt-get install exim4
dpkg-reconfigure exim4-config

Полезные команды для управления

Запустить и погасить виртуальную машину используются

lxc-start -n myvm -d
lxc-stop -n myvm

Параметр -d в случае старта означает запуск в режиме демона. Если его не указать, то getty захватит текущую консоль (что бывает полезно, если не удаётся подключиться по SSH).

Получить краткую информацию о статусе машины можно с помощью

lxc-info -n myvm

Заключение

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

PS

Статья устарела. Более качественный способ приведён в дебиановском мануале. И, что важно, постоянно обновляется.

Ограниченный SFTP-доступ на сервер

Часто возникает задача дать доступ на сервер в определенную директорию по протоколу sftp, чтобы при этом не было доступа в весь корень файловой системы. Т.е. используя технику chroot. Делается это следующим образом.

Сначала создается пользователь в системе. Обычно по sftp заходят для правки контента и группа пользователя назначается общей для этого рода пользователей (например, www-data). Всё это делается опциями к adduser или useradd.

Далее в /etc/ssh/sshd_config созданному пользователю newuser добавляется кусок конфига, который определяет параметры входа и chroot:

Match User newuser
	ChrootDirectory %h
	ForceCommand internal-sftp
	AllowTcpForwarding no
	X11Forwarding no

После изменения конфига, естественно, нужно рестартануть sshd.

На этом все не заканчивается. Вот что гласит мануал sshd_config:

ChrootDirectory
Specifies the pathname of a directory to chroot(2) to after authentication. All components of the pathname must be root-owned directories that are not writable by any other user or group. After the chroot, sshd(8) changes the working directory to the user’s home directory.

Из соображений безопасности, чтобы работал chroot, директория пользователя должна быть от пользователя root (при этом группа может быть не рутовой). Выполняем это требование, voila и всё работает.

Также для безопасности обычно имеет смысл отключить шелл пользователя

	usermod newuser -s /bin/false

PS: Это все применимо именно для sftp. К сожалению, для scp это не работает и при попытке подключиться по ssh/scp произойдет ошибка.

Полезные твики bash

В этой статье наиболее полезные способы быстрой и продуктивной работы с коммандной строкой bash. Предполагается, что читатель уже несколько знаком с коммандной строкой, поэтому совсем тривиальных вещей, вроде использования Tab для автодополнения, здесь нет. В комментарии приветствуются другие полезные «твики» bash.

Алиасы

Листинги

alias ll='ls -l'
alias l='ls -lA'

Часто эти опции уже включены в .bashrc, но закомментированы. В Debian, например, в конфиге это реализовано так

# export LS_OPTIONS='--color=auto'
# eval "`dircolors`"
# alias ls='ls $LS_OPTIONS'
# alias ll='ls $LS_OPTIONS -l'
# alias l='ls $LS_OPTIONS -lA'

Остается раскомментировать нужные строчки. При этом в нагрузку получаем цветовую подсветку директорий.

Часто используемая команда по поиску процесса с определенным именем:

alias pg='ps aux | grep '

Просмотр наибольших файлов/директорий в гигабайтах и мегабайтах соответственно:

alias dug='du -h | grep ^[0-9.]*G | sort -rn'
alias dum='du -h | grep ^[0-9.]*M | sort -rn'

Полезности для скриптов

Иногда бывает полезным поймать сигналы, посылаемые ОС скрипту. Например, при нажатии Ctrl-C.

trap control_c SIGINT
trap control_c SIGTERM

Часто используемые команды

Часто бывает необходимо найти файл, в котором имеется определённая подстрока. Сделать это можно с помощью стандарной утилиты grep командой:

grep -rl

Горячие клавиши bash

  • Ctrl+w — удаляет слово перед курсором в строке,
  • Ctrl+u — удаляет все символы до начала строки,
  • Ctrl+k — удаляет все символы до конца строки,
  • Ctrl+y — вставляет удалённые вышеуказанными сочетаниями символы,
  • Ctrl+r — производит обратный поиск по истории команд,
  • Ctrl+l — очищает экран,
  • Ctrl+z — останавливает исполнение текущей команды (продолжить можно с помощью bg или fg),
  • Ctrl+d — выход из сессии.

История команд bash

В администрировании Linux (да и UNIX тоже) очень удобно пользоваться командами из истории. Содержание истории просматривается с помощью вызова history. Команду из истории можно выполнить по её номеру в списке например так:

history | less
!45

При этом последняя команда вызывается более просто, без указания номера выполнением !!.

Обратный поиск по истории команд вызывается с помощью Ctrl+R, например:

(reverse-i-search)`smart': smartctl -x /dev/sdd | less

Взять аргументы из одной из предыдущих команд можно сочетанием Alt+..

По умолчанию длина истории небольшая и если нет повышенных требований к безопасности её можно несколько увеличить добавлением в .bashrc строки:

export HISTFILESIZE=5000

Длинная история несколько понижает безопасность системы, особенно если в неё попадают всякие «интересные» команды. Поэтому, на критичных системах размер истории большой делать не стоит. Сбросить историю можно

history -c

Избежать добавления команды в историю можно начав её с пробела. Тогда исполненная инструкция в историю не попадает.

Уязвимость SSLv3 POODLE

В протоколе SSLv3 обнаружена уязвимость, поэтому все сервисы, завязанные на него следует переконфигурировать. А если точнее, отключить SSLv3 вообще. Ниже кратко как это делается.

nginx

В энжинксе явно разрешаем только хорошие протоколы

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

apache2

В апаче и ниже — запрещаем.

SSLProtocol all -SSLv3 -SSLv2

dovecot

ssl_protocols = !SSLv3 !SSLv2

postfix

smtpd_tls_mandatory_protocols=!SSLv2, !SSLv3

Тесты SSL уязвимости

Здесь можно проверить на уязвимость свои серверы, а здесь — браузер.
Другие параметры SSL можно проверить с помощью этого теста, кроме этого легко гуглится ещё много подобных сервисов.

Дополнительно

Естественно, все демоны после изменения конфигов релодятся или рестартятся.

PS: Разработчики nginx отключили SSLv3 в конфигах. На новых версиях этого делать уже не требуется.

Безопасность

Бородатый анекдот:

Два геолога в тайге встречают медведя. Ружья нет. Один геолог бросается бежать, а второй кричит ему вслед:
— Бесполезно, ты всё равно не сможешь бежать быстрее медведя!
— А мне не нужно бежать быстрее медведя. Мне всего лишь достаточно бежать быстрее тебя!

 

В большинстве случаев этот подход оптимален и в компьютерной безопасности.