пятница, 30 декабря 2011 г.

Oracle и DNS

Даже не знаю, с чего начать статью. :)

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

Вскрытие показало, что больной умер в результате вскрытия ;)

Итак, в чем суть проблемы?

Суть проблемы - во взаимоотношениях Oracle RDBMS, Oracle Net и DNS.

Во-первых, о проблеме запуска.

В БД Oracle хардкодом вбито разрешение собственного имени сервера при старте базы, а точнее, при старте процесса SMON. На некоторых платформах (например, AIX5L), у которых при настройке разрешения имен первым не используются в обязательном порядке файлы hosts, а только затем DNS, в случае недоступности сервера (серверов) имен база отказывается стартовать.

Кстати, на Солярисе такие случаи мне лично незнакомы, поскольку в файле /etc/nsswitch.dns всегда первым идет разрешение посредством files:


# You must also set up the /etc/resolv.conf file for DNS name
# server lookup. See resolv.conf(4).
hosts: files dns


Соответственно, такой проблемы не возникает. Но так резолвер по умолчанию настроен не на всех платформах.

А вот данное поведение СУБД совсем не хорошо задокументировано. Во всяком случае, большими красными буквами это в руководствах не выделено и с разбегу не находится. Ровно до момента, когда вы с этим сталкиваетесь и лезете в службу технической поддержки с кодом ошибки. Причем в ноте саппорта сказано лишь "Проверьте /etc/resolv.conf".

На платформе AIX симптом недоступности DNS подтверждается затяжным коннектом к серверу по SSH, в котором по умолчанию также включено UseDNS yes.

Вторая проблема - с отсутствием подключения серверов приложений к работающей на момент недоступности DNS-серверов базе данных - менее очевидна. 

Для клиентов база данных выглядит полностью недоступной. И они начинают гневно доставать DBA. ;)

Диагностируется данная проблема посредством файла sqlnet.log, фиксирующим таймауты ns при установлении клиентских соединений.

Самый главный вопрос - что делать?

Первое и самое правильное решение: иметь в /etc/resolv.conf не менее двух внутренних (по отношению к локаальной сети) и полностью контролируемых DNS, один из которых должен быть всегда доступным - в частности, доступным по сети (обратите внимание, если сервер работает, но пакеты теряются - эффект будет примерно таким же: периодически пропадающие соединения с базой!).

Второе - сменить либо настройки резолвера сервера - на использование первым файла /etc/hosts и лишь после него - DNS, либо ОС сервера. ;)

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

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

пятница, 23 декабря 2011 г.

Джинн и бутылка

Первое правило волшебника гласит:
Люди глупы. Люди глупы, и, если правдоподобно объяснить, почти все поверят во что угодно. Люди глупы и могут поверить лжи, оттого что хотят верить, будто это правда, или оттого что боятся знать правду. Головы людей полны всякими знаниями и верованиями, большинство из которых ложны, но все же люди в это верят. Люди глупы: они редко могут отличить правду от лжи, но не сомневаются, что способны на это. Тем легче их одурачить.

Первое правило волшебника, Т.Гудкайнд


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

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

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

Нет, это еще не клиническая идиотия. Хотя и производит  такое впечатление при более детальном рассмотрении.

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

Почти все мало-мальски серьезное, за что берутся люди, делается именно по принципу "Война план покажет". Ни сколько-нибудь серьезного обдумывания далеко идущих последствий, ни мало-мальски приличных горизонтов планирования. "А, после нас хуч потоп!"

Всего лишь три примера.
  1. Интернет. 
  2. Wi-Fi. 
  3. Социальные сети.
Вы хотите об этом поговорить?

Пожалуйста.

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

Никто и не думал закладывать ничего подобного рубильникам, дабы вырубать города и страны в случае чего. Чего? А никто не думал, чего может быть.

Ладно.

Джинна выпустили.

Всего через пяток лет интернет сначала наводнило порно в масштабах Всемирного Потопа. А фиг ли? Швабода же! Демократия! Анонимусы!

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

Начались поиски затычки.

"Товарищи! Потерпите еще год! Затычку уже ищут!"

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

Кстати, как вам лично понравится автомобиль для храбрецов без тормозов? М?

Но я отвлекся. 

Дальше - больше.

Внезапно выяснилось, что в отсутствие тормозов тормозить все-таки как-то надо, в некоторых отдельно взятых случаях или отдельно взятых странах.

Метод ста китайцев, построивших с этой целью пресловутый Голден ШитГолден Шилд, собссна, работает лишь в одной отдельно взятой стране. Где эти сто китайцев обитают. И то - фигово-фигово. Пакетик дырочку-то найдет. ШитТо бишь Шилд всегда проигрывает Сворду.

Ну ладно, хрен с вами. Пытаетесь контролировать, дабы джинн слишком уж не буйствовал - хрен с вами, пытайтесь. Но брехать-то так неуклюже зачем? "Ах-ох, мы ничего не фильтруем и не блокируем! Это они, супостаты, у них вот весь сайт работает, но вот эта отдельно взятая сцылочка, вредная для вашего душевного здоровья, она по техническим проблемам на стороне сервера недоступна, панимаишь! И это на сервере, выдерживающем 200 миллионов посетителей в день, да, верьте нам!"

Чувствуете, автомобильчик-то без тормозов by design! Тормоза изобрели трусы! Поэтому давайте тормозить во-он той веточкой, которую сорвали с придорожного растущего деревца.

Однако, я отвлекся.

Что? Нельзя было просчитать тогда, 15 лет назад, во что все выльется? Стоп, при чем тут Нострадамус? Плохо знакома природа людей? Любопытство, основной инстинкт, бесконечное желание обезьянок общаться? Не нужно быть Нострадамусом, чтобы знать об этом.

Ладно. Проехали.

С Wi-Fi вообще особый и милейший разговор. Удобная - в принципе! - технология оказалась мало того, что изначально дырявой, так еще и двойного назначения. А к тому моменту, когда выяснилось, что она преимущественно хороша для хаксоров, и начали шевелить мозжечками, говоря, что не хилтон бы лицензировать-контролировать-и всякое такое, поезд уже ушел. Опа! - проснулись, а кругом сплошные точки доступа! Ну-кося, конфискуй-ка столько девайсов из личной собственности у собственных граждан!

Гм. Совок догадывался пишмашинки и факсы с ксероксами контролировать, а современные умники не допетрили, чем обернется беспроводной доступ? Простите, чем-чем, вы говорите, вы думаете?

Социалки вообще песнь песен.

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

Что имеем теперь? Терабайты пиратского контента, детской порнографии, а, самое главное, рассадник погромов и революций!

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

Ничего, что искусственный интеллект остановился в развитии на состоянии 1965 год примерно? Ничего, что анализ такого эвереста дерьмаданных в реальном времени лежит за пределами законов сохранения и квантовых лимитов?

Что, не ждали? Что остальные хомо тоже, в общем-то, оборудованы головным мозгом и приспособят ножички не только хлебушек порезать, но и оппоненту кишочки выпустить?

Давайте теперь героически порешаем и эту возникшую проблему. Попробуем ее решением судов позакрывать и попугать анонимусов, делая пальчиками "козу" и приговаривая "Бу! Пачпорт покаж! Или его скан, тащемта!". История с Салманом Рушди (веселюсь) и его паспортом в Фейсбуке меня вообще позабавила, особенно в свете того, что я писал раньше.

(с иронией)

А уже есть и инет, и Wi-Fi, и Тор с Фринетом. Что, нашли 6 миллиардов дурочек, которые не найдут лазейку или целые ворота?

Вернемся к нашим барашкам.

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

Рулевые-то, вообще говоря, с завязанными глазами рулят. По большей части.

В IT всему вышесказанному, между нами, есть определение.

То, о чем я писал до сих пор, называется в IT "Реактивное администрирование".

В переводе на простой русский язык это звучит так - "Гром не грянет - мужик не перекрестится".

В профессии это считается плохим тоном, однако так живет 95% профессионалов и не жужжат, что называется. В общем-то, так 95% всех человеков живет.

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

Называется она "Проактивное администрирование".

Так же, простыми словами - "Видимость ноль, иду по приборам, однако через 15 копеек поворот налево".

(с иронией)

То, к чему оказался не склонен капитан Очевидность "Титаника".

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

Что, хорош критиковать? Пора предлагать?

А как же. Сейчас предложу. Собственно, уже предложил.

Проактивное администрирование.

Эй, вы, там! Наверху!

Существует такой зверь, как аналитик! Нанимайте аналитиков, держите волосатые лапы на всех пульсах, до которых дотянетесь, просчитывайте ситуацию хотя бы лет на 10 вперед, а не просто пилите и откатывайте! Помните, что вы у руля, а не у корыта! И тогда - может быть! - вас пронесет от попадалова прямиком в айсберг через пару-тройку лет и не будет у вас прекрасных глазок тонущего Ди Каприо!

вторник, 20 декабря 2011 г.

ZFS: Не шутите с CoW!

Преамбула

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

В этой связи мне страшно нравится передача Discovery "Как это работает?" Пора такие видеоликбезы по IT выкладывать на YouTube, как мне представляется. Где популярно, языком телепередач, внушать IT-общественности, что законы физики вообще и законы сохранения в частности, в общем, в IT тоже действуют.

Жалоба CoWбоя

А теперь к делу.

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

Что в переводе на простой русский язык означает - "Транзакционная семантика и запись измененных данных на новой место".

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

Приведу простой пример.

Допустим, у вас есть сторидж пул ZFS общим объемом 1 Тб. При этом он заполнен на 50%, и количество файлов на этих 50% (т.е. на 500 Гб) составляет, скажем, 10 млн штук. При этом приложение/приложения каждый час обновляет половину из них, что составляет в гигабайтах, допустим, 250 Гб.

Каждый раз, когда происходит транзакционное обновление 250 Гб, эти 250 Гб записываются в новое место.

Через 3 часа фактически свободное пространство на сторидж пуле заканчивается*.

Что произойдет после этого?

Солярис 10 в этой ситуации принудительно размонтирует пул. Последующее монтирование приведет к инициированию процедуры scrub, что, в случае 10 млн файлов, означает, что пул нельзя будет смонтировать до завершения полной проверки всех контрольных сумм приблизительно на протяжении суток-двух.

__________________________
* Я сознательно максимально упрощаю пример. Да, мне известно и о наличии лога намерений (intent log), который, если не вынесен на отдельные устройства, выделяется в пространстве пула, и о наличии включенного по умолчанию кэша L2, выделенного там же. С учетом их существования, при заданных в примере начальных условиях и при таком темпе изменений файловой системы все закончится еще быстрее. Примерно в три-четыре раза, в зависимости от разового объема записи и количества шпинделей пула. Опять-же, грубо. Желающие могут провести натурный эксперимент, в стиле "Разрушителей легенд" дабы лично убедиться в действии законов физики. :)
__________________________

Почему так?

По определению. Так написана файловая система.

Эффект, в общем, не нов. Некоторые неосиляторы концепций от IT еще пару лет назад лично убедились в существовании законов физики, когда, при 90% заполнении пула, обнаружили резкую деградацию производительности ZFS. Ну, еще бы! А куда, по-вашему, драйвер ФС должен писать копии измененных блоков в рамках транзакций? На Великий Небесный Сервер?

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

Что, не ждали?

Сюрприз! Концепции желательно не только курить, их желательно также понимать. Что требует уже наличия функционирующего головного мозга. ;)

Что делать и кто виноват?

Виноват, конечно, разработчик файловой системы, кто ж еще-то... Понапишут, блин, а тут потом сиди, разбирайся, кто дурак. Еще и исходники читай... Само должно работать! Искаропки!

А если серьезно?

Планировать СХД. С карандашом в руках. Оценивая не только потребную латентность, пропускную способность или IOPS, но и запас свободного пространства с учетом примерного планируемого объема дисковых транзакций и их темпа в единицу времени.

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

Как метко выразился один джентльмен (правда, немного по другому поводу), жесткий диск сейчас стоит дешевле лопаты дерьма. Кто мешает хотя бы 50% запас по дисковому пространству иметь? Ах, вы не ждали такого поведения файловой системы... Ну, что ж.  Ошибки в генах программно не исправляются.

Что делать, если все-таки влипли? Прохлопали ушами и пул отвалился?

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

Да, есть ломовое средство. Удалить в безопасном режиме /etc/zfs/zfs.cache, перезагрузиться в опасный режим, разрушить пул, создать заново, и восстановить данные - хотя бы частично - со снапшотов (разумеется, если вам хватило ума организовать процедуры резервного копирования. Что, как показывает практика, свойственно далеко не всем). Не допуская уже чрезмерного заполнения.

Не думаю, однако, что пользователей сервера устроит величина даунтайма и такое отношение к их данным.

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

Если пул, после завершения проверки, все-таки удалось импортировать, первым делом надо попытаться удалить лишние данные. Если это, опять-таки, удастся сделать.

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

Не надо жадничать.

вторник, 22 ноября 2011 г.

Камо грядеши?

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

Я долго не мог понять, как бы получше сформулировать то, что не дает мне покоя.

Попробую своими словами.

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

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

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

Сначала немного школоло.

Давайте вспомним три основных вида аутентификации, существующие в природе.

Первый - "У меня есть". Ключ, смарт-карта, кредитка, крипто-токен.
Второй - "Я знаю". Пароль, отзыв, секретное слово, фразу, ответ.
Третий - "Я являюсь". Отпечаток пальца, голоса, сетчатки глаза.

Все три не являются идеальными.

Первый - то, что у вас есть, можно (и нужно) банально украсть. Всякие замки и засовы от хороших людей, как известно. Костыли типа пин-кодов являются очевидным фейком, достаточно вспомнить, как работают кардеры. "Нельзя взломать лишь совесть, да и то лишь у некоторых". Ключ можно потерять или задействовать под принуждением.

Второй - хороший пароль большая проблема. Которая в генах его носителя. И которая называется человеческой памятью. Средний человек неспособен физически держать в голове мало-мальски сложный пароль. Недавняя серия взломов аккаунтов на мэйл.ру наглядно  продемонстрировала проблему. Отсутствие защиты от брутфорса и мощь атакующих привела к тому, что были взломаны даже цифробуквенные десятизнаки, без единого признака осмысленности. Взрывной рост мощи числогрызок и доступность этих машин простым смертным делает уязвимыми даже 14-значные генераторные пароли. На все это наложена проблема крайней тупости пользователей и непонимание ими принципов социальной инженерии (что было описано сто лет назад еще Брюсом Шнайером) - вопрос восстановления пароля - "Девичья фамилия вашей матери?" Сколько было взято аккаунтов таким способом - страшно подумать.

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

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

Инфраструктура PKI, несмотря на повсеместные дифирамбы дилетантов, как и было предсказано все тем же Брюсом, страдает целым рядом фатальных недостатков концептуального характера и за серьезную систему безопасности считаться не может вообще, до сих пор, несмотря на повсеместное распространение. В частности, именно в области аутентификации.

Но отставим пока enterprise authentification  в сторону. 

Поговорим о другой проблеме. Которую создали себе самостоятельно и собственноручно.

Я о миллионах хомячья в социальных сетях и аутентификации в веб-среде.

Традиционная аутентификация в вебе в большинстве случаев завязана на реальный e-mail пользователя с подтверждающей проверкой. Туда же обычно завязываются службы восстановления паролей, вспомните хотя бы ICQ.

А теперь внимание. Вдумайтесь. Для целей аутентификации используется один из самых древних и незащищенных протоколов - SMTP/POP3.

Я оставляю за скобками всякие блэкберри с их черным ходом для спецслужб. Или навороты Гугла с доступом к почте под SSL. Это все паллиативы, причем дерьмовые палливативы, если хорошо подумать и поднять глазки вверх, вспомнив о пробоях SSL. Эти "решения" я даже комментировать не хочу. Любому здравомыслящему теху очевидно, что это - не решение.

Ваш пароль передается по фактически открытому протоколу, S/MIME так и не прижился в более-менее приличном исполнении.

Оставим за скобками также так называемое шифрование, применяемое в повседневной практике. Существование OpenCL и устройства с названием Tesla не оставляет камня на камне от прикладных шифров. На видеокарте класса nVidia 8800 хэш MD5 берется за минуты на писюке-локалхосте.

Вернемся к проблеме аутентификации.

То, что электронная почта не может являться основой для аутентификации, на мой взгляд, очевидно. Отправка SMTP-почты телнетом от имени ЛЮБОГО адреса в дым разбивает идею тождества личности с ее мэйлом. Спамеры это ежедневно доказывают. Всякого рода disposable-мэйлы из той же серии.

Это прекрасно поняли некоторые социалки, которые стали подпирать аутентификацию пользователей сотовыми телефонами.

Идея опять-таки бредовая с учетом существующих реалий. Сим-карты клонируют. Не во всех странах действует ублюдочное законодательство о предьявлении паспорта при покупке сим-карты. Помимо существования необходимости такой вещи, как, например, прайвиси и необходимости/обоснованного желания остаться в ряде случаев анонимным. (усмехаясь) Скажете, на кой? Я простой человек, мне скрывать нечего? Расскажете это, кстати, Евгению Касперскому. Русскому человеку прайвиси - совершенно чужеродная концепция, в большинстве случаев. 

Но я отвлекся.

Вернемся к нашим баранам. У нас есть проблема с аутентификацией в Web 2.0. 

Причем проблема практически нерешаемая. 

Скан паспорта? Фейсбук и ВКонтакт пытаются использовать этот бред. Однако хочу процитировать один абзац из вышеприведенной ссылки:

"Личность в интернетах вообще НЕ МОЖЕТ доказать факт собственного существования. Фотографии, описания жизнедеятельности, отсканированные документы — доказательством не являются.
В интернетах нет ни меня, ни вас. Вещественны только мысли, а сама личность существует в форме «ментальной субстанции», которая является креативной единицей общего информационного поля."

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

Скан паспорта? Состряпаем в шопе или откорректируем скан своего паспорта. Редактирование растровых изображений - милое дело.

Кстати, помните ту забавную историю с Фейсбуком и Ахмедом Салманом Рушди? Да-да, тем самым. Которого отказались регистрировать под авторским именем даже после предъявления скана паспорта, результатом чего была схватка Салмана с администрацией Фейсбука.

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

А аутентификация на основе аккаунтов социалок и еще более бредовая вещь. Даже всевозможные OpenID являются фейком. Поскольку неверны концепции и предпосылки первичной аутентификации.

Одно время в вебе 1.0 действовала аутентификация на основе проверки существования кредитной карты путем фиктивной транзакции суммой 1 доллар. Однако и это фейк. Так как кредитка не является уникальным неподделываемем артефактом.

Банки в колл-центрах используют полифакторную аутентификацию клиента на основе целой серии открытых и закрытых данных. Но опять-таки в концепции "я знаю" (второй метод), и лишь с определенной степенью достоверности. Самая надежная аутентификация банками осуществляется в виде личного предъявления все того же документа, удостоверяющего личность.

Из всего вышесказанного следует один вывод. Я в начале статьи сказал, что аутентификация и неотрекаемость не связаны между собой.

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

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

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

Контрвопрос. Допустим, вы - преступник. Как доказать вашу виновность в преступлении, совершенном, скажем, в интернете?

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

Опять-таки, возвращаясь к заголовку, существует ли в природе вообще сколько-нибудь достоверный способ убедиться, что человек именно тот, за кого себя выдает? Или что это тело именно ТОГО человека?

В общем-то, таких способов два.

Первый общеизвестен. Многоточечная проверка знания общих секретов, известных лишь очень ограниченному кругу лиц. Такая примитивная концепция, как "разделяемый общий секрет" все еще актуальна IRL. Особенно при достаточной глубине проверки и надежности проверяемых данных. "В каком баре мы с тобой надрались в Рио в 19мохнатом году и как звали проститутку, который ты набил морду?" ;)

Второй менее очевиден, и, в общем-то, менее достоверен. Молекулярный анализ ДНК, при условии, что у нас есть эталонный образец ДНК, полученный в условиях, исключающих подмену. Я не случайно выделил данную фразу. Как, например, США убедились, что перед ними Усама Бин Ладен? У них был образец ДНК маленького Усамы в роддоме? (оставим роддомы в покое. Аутентичность детей знают лишь акушерки и это отнюдь не исключает ни подмены, ни путаницы детей - намеренной или случайной).

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

Так что, "Никогда не говори, что человек мертв, пока ты не увидишь его тела. Но даже тогда ты можешь ошибиться" (С) Фрэнк Херберт, "Дюна".

Одиннадцать негритят

Десятого ноября вышел одиннадцатый Солярис. Встреченный у неофитов бурными продолжительными аплодисментами. Которые, по ходу, список фич Соляриса впервые увидели.

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

Проблема раз. И какая проблема!
Сюрприз! Вы не можете мигрировать посредством Live Upgrade ваши боевые сервера в датацентре, работающие 24x7. Феерический даунтайм. Предложенные выше варианты миграции я вообще всерьез не рассматриваю. Это булшит, которым Оракл может подтереться.

Проблема два. 

Походу, для индопрограммистов Оракла максима "Совместимость важнее производительности" не писана. Они просто во время ее провозглашения даже в проекте отсутствовали.

Несовместимо все. Пакетный интерфейс. Интерфейс патчей. Интерфейс миграций и апгрейдов. ABI. Вы больше не сможете исполнять ни единого 32-битного унаследованного приложения и ни единого софта с Sunfreeware

Мало того, что вам придется полностью переустанавливать систему. А перед этим тестить приложения на совместимость утилитой, которую заботливо подготовил Оракл. Нет никакой гарантии, что у вас запустится что-то из старого софта. Опенсурс тоже не забыли. Нет гарантии, что он СОБЕРЕТСЯ на 11ке.

Проблема три.

Выброшенные деньги.

Все приличные старые процессоры больше не поддерживаются. До SPARC IV+ включительно. Которые только и были нормальными процессорами у Сан. Поддерживается только фейковый UltraSPARC.

Ваше оборудование энтерпрайз-класса, для которого еще не настал EOL и которое еще не ROI - можете сдавать его в утиль на вес. Если желаете посадить туда 11ку - обломайтис. Только десятка. Которую, конечно, будут поддерживать до 2014го года. С качеством ораклового саппорта, которое хорошо известно.

Оракл изящно слил всю инсталляционную базу Сан. Ребята, вы нафиг не нужны Ораклу! Ни вы, ни ваша ОС. Которая недвусмысленно двигается в сторону Линя в оракловом исполнении - прокладка под СУБД. Солярис как система общего назначения - и великолепная в прошлом система - сливается в трэш.

Думайте о смене платформы, джентльмены.

Теперь к делу. Как все-таки осуществить миграцию с действующих систем под 10кой на 11ку? 

Чисто теоретически это возможно. С рядом оговорок.

Первое. Про LU забудьте. Он несовместим в 10ке и 11ке. Даунтайм НЕИЗБЕЖЕН, и он будет нешуточный. Будет переустановка.

Второе. Сначала надо убедиться, что 11ка вообще запустится на вашем железе. Можно это сделать при помощи LiveUSB.

Третье. На действующей 10ке надо проверить приложения на совместимость с 11кой. Той самой тулзой. В случае какой-либо несовместимости вашего софта ищите либо обход либо веревку. Софт в исходниках также стоит проверить.

Четвертое. Сделайте физический бэкап вашей системы. Существует риск, что придется откатиться.

Пятое. Если вы сидите на RAID под ufs - готовьтесь практиковаться в выполнении Live Upgrade на 10ке. 

В двух словах.

Единственная возможность более-менее легко выполнить переход, при выполнении всех вышеперечисленных условий, это, как ни странно, виндузятный подход "ОС на диске С:, данные на диске D:".

Поясню. Если вы сидите на, скажем, зеркалированном пуле ZFS под последним апдейтом десятки, то версия пула у вас такая же, как и у 11ки. 29я. Если при этом у вас почти не установлено в корневом пуле никакого софта, кроме системы (ну или его минимум), а все данные и прочие приложения умненько вынесены на некорневые пулы, то, считайте, что существует ненулевая вероятность успешной миграции.

От вас потребуется сохранить некоторые конфиги, специфичные для вашего софта, которые лежат в руте. Остановить приложения. Экспортировать несистемные пулы. Установить начисто на слайс корневого пула 11ку. С выносом десятки. Импортировать пулы данных. Восстановить конфиги приложений на корневой пул. Стартовать сервисы, если предварительная проверка показала совместимость приложений с 11кой. Возможно - и почти наверняка - потребуется либо пересборка, либо перелинковка прикладного софта. Напоминаю, что ABI изменился.

Противоестественного секса много. Спасибо Индии и лично Лоуренсу Т. Эллисону за это. Но других вариантов просто не существует.

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

Покойся с миром, Solaris. R.I.P.

вторник, 11 октября 2011 г.

IPFilter: Как скрыть существование файрвола?

Я несколько раз писал о своем подходе в настройке файрвола Solaris. Основных принципов два - мы создаем файрвол закрытого типа и мы не скрываем его существования

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

Как сканеры определяют существование файрвола?

Очень просто. Если при открытии сессии (посылке пакета SYN) возникает таймаут (файрвол глотает пакет и молчит), значит, порт определяется как filtered. 

Штатное поведение стека TCP в такой ситуации следующее. Есть порт, за которым нет сервиса - стек отвечает пакетом RST.

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

# Rules groups setup
# Group 100 - Blocked networks/packets on any interface
# Group 100 setup
block in all head 100
# Group 200 - Opened incoming ports on e1000g0
# Group 200 setup
pass in on e1000g0 head 200

# ---------------------
# Common blocking rules
# ---------------------

# Block all IP fragments
block in quick all with frag group 100

# Block all short IP fragments
block in quick proto tcp all with short group 100

# Block any IP packets with options set in them
block in quick all with ipopts group 100

# Block OS fingerprint attempts
block in log first quick proto tcp all flags SF/SF group 100
block in log first quick proto tcp all flags SF/SFRA group 100
block in log first quick proto tcp all flags /SFRA group 100
block in log first quick proto tcp all flags SFUP/SFUP group 100
block in log first quick proto tcp all flags FUP/FUP group 100
block in log first quick proto tcp all flags F/F group 100
block in log first quick proto tcp all flags U/U group 100
block in log first quick proto tcp all flags P/P group 100

# Anti-spoofing rules
#block in quick from 192.168.0.0/16 to any group 100
block in quick from 172.16.0.0/12 to any group 100
block in quick from 10.0.0.0/8 to any group 100
block in quick from 127.0.0.0/8 to any group 100
block in quick from 0.0.0.0/8 to any group 100
block in quick from 169.254.0.0/16 to any group 100
block in quick from 192.0.2.0/24 to any group 100
block in quick from 204.152.64.0/23 to any group 100
block in quick from 224.0.0.0/3 to any group 100

# Finally block all unmatched
block in quick all

Сканер показывает закрытые порты как отфильтрованные:

Starting Nmap 5.21 ( http://nmap.org ) at 2011-10-11 16:54 Центральная Азия (зима)
NSE: Loaded 36 scripts for scanning.
Initiating ARP Ping Scan at 16:54
Scanning 192.168.192.3 [1 port]
Completed ARP Ping Scan at 16:54, 0.31s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 16:54
Completed Parallel DNS resolution of 1 host. at 16:54, 5.64s elapsed
Initiating SYN Stealth Scan at 16:54
Scanning 192.168.192.3 [1000 ports]
Discovered open port 2222/tcp on 192.168.192.3
Completed SYN Stealth Scan at 16:54, 8.73s elapsed (1000 total ports)
Initiating Service scan at 16:54
Scanning 1 service on 192.168.192.3
Completed Service scan at 16:54, 6.00s elapsed (1 service on 1 host)
Initiating OS detection (try #1) against 192.168.192.3
Retrying OS detection (try #2) against 192.168.192.3
NSE: Script scanning 192.168.192.3.
NSE: Starting runlevel 1 (of 1) scan.
Initiating NSE at 16:54
Completed NSE at 16:54, 0.53s elapsed
NSE: Script Scanning completed.
Nmap scan report for 192.168.192.3
Host is up (0.00s latency).
Not shown: 999 filtered ports
PORT     STATE SERVICE VERSION
2222/tcp open  ssh     (protocol 2.0)
| ssh-hostkey: 1024 3f:8d:b6:e2:68:1a:f2:c7:2c:3e:00:27:9d:96:64:bb (DSA)
|_2048 01:63:b5:7c:cf:b9:e8:b6:1d:68:9c:8b:dd:53:39:a3 (RSA)
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at http://www.insecure.org/cgi-bin/servicefp-submit.cgi :
SF-Port2222-TCP:V=5.21%I=7%D=10/11%Time=4E942071%P=i686-pc-windows-windows
SF:%r(NULL,13,"SSH-2\.0-Fuck\x20YEA!\r\n");
MAC Address: 08:00:27:0C:6F:75 (Cadmus Computer Systems)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running (JUST GUESSING) : Sun Solaris 10|9 (92%)
Aggressive OS guesses: Sun Solaris 10 (92%), Sun Solaris 10 (SPARC) (92%), Sun Solaris 9 or 10 (SPARC) (88%)
No exact OS matches for host (test conditions non-ideal).
Uptime guess: 0.073 days (since Tue Oct 11 15:09:20 2011)
Network Distance: 1 hop
TCP Sequence Prediction: Difficulty=263 (Good luck!)
IP ID Sequence Generation: Incremental

HOP RTT     ADDRESS
1   0.00 ms 192.168.192.3

Read data files from: C:\Program Files\Nmap
OS and Service detection performed. Please report any incorrect results at http://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 29.36 seconds
           Raw packets sent: 2088 (97.006KB) | Rcvd: 18 (1030B)

Вот как выглядит наличие файрвола:

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

Можем ли мы скрыть наличие файрвола от сканера? С учетом вышесказанной особенности, и, если закрыть глаза на то, что система начнет при сканировании отсылать встречные пакеты RST (что может быть проблемой при непиринговом трафике) - одной строчкой. Достаточно переписать финальное блокирующее правило следующим образом:

# Finally block all unmatched
block return-rst in quick all

Давайте для чистоты эксперимента честно рестартуем ОС и посмотрим, что мы сможем узнать посредством сканера теперь.

Starting Nmap 5.21 ( http://nmap.org ) at 2011-10-11 17:06 Центральная Азия (зима)
NSE: Loaded 36 scripts for scanning.
Initiating ARP Ping Scan at 17:06
Scanning 192.168.192.3 [1 port]
Completed ARP Ping Scan at 17:06, 0.16s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 17:06
Completed Parallel DNS resolution of 1 host. at 17:06, 5.64s elapsed
Initiating SYN Stealth Scan at 17:06
Scanning 192.168.192.3 [1000 ports]
Discovered open port 2222/tcp on 192.168.192.3
Completed SYN Stealth Scan at 17:06, 1.53s elapsed (1000 total ports)
Initiating Service scan at 17:06
Scanning 1 service on 192.168.192.3
Completed Service scan at 17:06, 6.00s elapsed (1 service on 1 host)
Initiating OS detection (try #1) against 192.168.192.3
Retrying OS detection (try #2) against 192.168.192.3
NSE: Script scanning 192.168.192.3.
NSE: Starting runlevel 1 (of 1) scan.
Initiating NSE at 17:06
Completed NSE at 17:06, 0.28s elapsed
NSE: Script Scanning completed.
Nmap scan report for 192.168.192.3
Host is up (0.00s latency).
Not shown: 999 closed ports
PORT     STATE SERVICE VERSION
2222/tcp open  ssh     (protocol 2.0)
| ssh-hostkey: 1024 3f:8d:b6:e2:68:1a:f2:c7:2c:3e:00:27:9d:96:64:bb (DSA)
|_2048 01:63:b5:7c:cf:b9:e8:b6:1d:68:9c:8b:dd:53:39:a3 (RSA)
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at http://www.insecure.org/cgi-bin/servicefp-submit.cgi :
SF-Port2222-TCP:V=5.21%I=7%D=10/11%Time=4E942331%P=i686-pc-windows-windows
SF:%r(NULL,13,"SSH-2\.0-Fuck\x20YEA!\r\n");
MAC Address: 08:00:27:0C:6F:75 (Cadmus Computer Systems)
Device type: general purpose
Running (JUST GUESSING) : Sun Solaris 9|10 (86%)
Aggressive OS guesses: Sun Solaris 9 or 10 (SPARC) (86%), Sun Solaris 10 (85%), Sun Solaris 9 (85%)
No exact OS matches for host (test conditions non-ideal).
Uptime guess: 0.003 days (since Tue Oct 11 17:02:38 2011)
Network Distance: 1 hop
TCP Sequence Prediction: Difficulty=257 (Good luck!)
IP ID Sequence Generation: Incremental

HOP RTT     ADDRESS
1   0.00 ms 192.168.192.3

Read data files from: C:\Program Files\Nmap
OS and Service detection performed. Please report any incorrect results at http://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 20.03 seconds
           Raw packets sent: 1135 (54.786KB) | Rcvd: 1045 (42.102KB)

Стала определяться операционная система (естественно, мы теперь отвечаем на пакеты сканера по всему диапазону закрытых портов), однако мы больше не видим существования файрвола. Порты помечены как закрытые.

Ну и визуально мы видим следующее:

Что и требовалось доказать. Хотя машина наглухо (кроме одного порта) закрыта файрволом, внешне она выглядит как незащищенная.

пятница, 7 октября 2011 г.

Повышение системных лимитов в Solaris 10

Хотя Солярис достаточно неплохо оптимизирован "из коробки", в некоторых случаях может возникнуть необходимость повысить системные лимиты, например, с целью масштабирования системы.

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

Как и обычно, все это делается через kernel tunables. Да, безусловно, можно попробовать поиграться с ulimit, НО - не все глобальные параметры можно изменить даже от рута.
Рассмотрим простенький пример. Прокси-сервер бизнес-центра. Должен масштабироваться по умолчанию. Железка достаточно сильная, однако в пиках нагрузки дает too many open files/too much user processes.

Вскрытие показывает, что на машине работает Squid с 192 редиректорами (суммарно). Ругается на процессы/открытые файлы явно прокси.

ulimit показывает нам маленькое количество файловых дескрипторов на пользователя и лимит в 27 с чем-то тысяч процессов на пользователя.

Мониторинг сервера показывает наличие свободных ресурсов по памяти и процессору (само собой разумеется, Squid не склонен к перегрузке процессоров).

Что ж, увеличиваем:

set rlim_fd_max=65536


Перезапускаем, смотрим. Ругань на файлы исчезла, ulimit показывает заданную величину.

Займемся процессами.

set max_nprocs=65536
set maxuprc=32767


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

Перезапускаем. Смотрим:

root @ ktulhu / echo max_nprocs/D | mdb -k
max_nprocs:
max_nprocs:     30000
root @ ktulhu /

root @ ktulhu / echo maxuprc/D | mdb -k
maxuprc:
maxuprc:        29995


Почему? Мы ведь увеличили таблицу процессов. Оказывается, мы забыли один лимитирующий параметр, впрямую связанный с max_nprocs - pidmax. Задаем:

set rlim_fd_max=65536
set pidmax=65536
set max_nprocs=65536
set maxuprc=32767


Перезапускаемся еще раз. Проверяем:

root @ ktulhu / # ulimit -a
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
open files                      (-n) 256
pipe size            (512 bytes, -p) 10
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 32767
virtual memory          (kbytes, -v) unlimited


Вот теперь порядок. Наша заданная величина max user processes установлена глобально, проблема решена.

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

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

четверг, 22 сентября 2011 г.

Solaris 10 update 10: Second Encounter

После памятного попадалова с версией корневого пула ZFS пришлось ждать обновления update 10 для Solaris 10. 

На удивление, оно вышло весьма скоро. Здесь.

Что ж, обновимся. Наш потерпевший сервер стоит на ZFS, регулярно обновляется, поэтому Live Upgrade должен пройти без проблем. 

Должен? Как бы не так!

Поступаем согласно best practices - обновляем перед началом пакеты Live Upgrade на версию из новой системы. Вот эти:

SUNWlucfg
SUNWlur
SUNWluu
SUNWluzone

Создаем новый BE:

root @ ktulhu / # lucreate -n s10x_u10wos_17b


Как бы не так. Не создается BE. Причем не создается в высшей степени странно. Снапшоты создаются, lustatus показывает, что BE создан, но при его создании вылетает ошибка. Удаление данного ущербного BE не проходит. ludelete не может размонтировать датасеты BE.

Что ж, не на тех напал. Размонтируем датасеты нового BE силовым методом, через zfs umount -f, и удаляем командами zfs destroy -r/-R. Удаляем недоношенный BE.

Много думаем.

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

Окей. Откатываемся до патченых пакетов update 9.

То же самое.

Окей. Нарушаем все best practices и откатываем пакеты LU на начальный релиз 9/10. Теоретически в 9 случаях из десяти LU с пакетами старого релиза невозможен. Но разве у нас есть выбор?

ВНЕЗАПНО - BE создается:

root @ ktulhu / # lucreate -n s10x_u10wos_17b


Все корректно. Отлично, готовимся к апгрейду нового BE - и не забываем про файл авторегистрации:

root @ ktulhu / # echo "auto_reg=disable" (здесь символ редиректа) /tmp/sysidcfg


Что ж, вперед:

root @ ktulhu / # luupgrade -u -n s10x_u10wos_17b -s /data/stage -k /tmp/sysidcfg

System has findroot enabled GRUB
No entry for BE in GRUB menu
Copying failsafe kernel from media.
62128 blocks
miniroot filesystem is
Mounting miniroot at
INFORMATION: Auto Registration already done for this BE .
Validating the contents of the media .
The media is a standard Solaris media.
The media contains an operating system upgrade image.
The media contains version <10>.
Constructing upgrade profile to use.
Locating the operating system upgrade program.
Checking for existence of previously scheduled Live Upgrade requests.
Creating upgrade profile for BE .
Checking for GRUB menu on ABE .
Saving GRUB menu on ABE .
Checking for x86 boot partition on ABE.
Determining packages to install or upgrade for BE .
Performing the operating system upgrade of the BE .
CAUTION: Interrupting this process may leave the boot environment unstable
or unbootable.
Upgrading Solaris: 100% completed
Installation of the packages from this media is complete.
Restoring GRUB menu on ABE .
Updating package information on boot environment .
Package information successfully updated on boot environment .
Adding operating system patches to the BE .
The operating system patch installation is complete.
ABE boot partition backing deleted.
PBE GRUB has no capability information.
PBE GRUB has no versioning information.
ABE GRUB is newer than PBE GRUB. Updating GRUB.
GRUB update was successfull.
INFORMATION: The file on boot
environment contains a log of the upgrade operation.
INFORMATION: The file on boot
environment contains a log of cleanup operations
required.
WARNING: <22> packages failed to install properly on boot environment .
INFORMATION: The file on
boot environment contains a list of packages that failed
to upgrade or install properly.
INFORMATION: Review the files listed above. Remember that all of the files
are located on boot environment . Before you activate
boot environment , determine if any additional system
maintenance is required or if additional media of the software
distribution must be installed.
The Solaris upgrade of the boot environment is partially complete.
Creating miniroot device
Configuring failsafe for system.
Failsafe configuration is complete.
Installing failsafe
Failsafe install is complete.

root @ ktulhu / # lustatus
Boot Environment Is Active Active Can Copy
Name Complete Now On Reboot Delete Status
-------------------------- -------- ------ --------- ------ ----------
s10x_u9wos_14a yes yes yes no -
s10x_u10wos_17b yes no no yes -

root @ ktulhu / # luactivate s10x_u10wos_17b
System has findroot enabled GRUB
Generating boot-sign, partition and slice information for PBE
A Live Upgrade Sync operation will be performed on startup of boot environment .
WARNING: <22> packages failed to install properly on boot environment .
INFORMATION: on boot
environment contains a list of packages that failed to
upgrade or install properly. Review the file before you reboot the system
to determine if any additional system maintenance is required.

Generating boot-sign for ABE
Saving existing file in top level dataset for BE as //etc/bootsign.prev.
Generating partition and slice information for ABE
Copied boot menu from top level dataset.
Generating multiboot menu entries for PBE.
Generating multiboot menu entries for ABE.
Disabling splashimage
Re-enabling splashimage
No more bootadm entries. Deletion of bootadm entries is complete.
GRUB menu default setting is unaffected
Done eliding bootadm entries.

**********************************************************************

The target boot environment has been activated. It will be used when you
reboot. NOTE: You MUST NOT USE the reboot, halt, or uadmin commands. You
MUST USE either the init or the shutdown command when you reboot. If you
do not use either init or shutdown, the system will not boot using the
target BE.

**********************************************************************

In case of a failure while booting to the target BE, the following process
needs to be followed to fallback to the currently working boot environment:

1. Boot from the Solaris failsafe or boot in Single User mode from Solaris
Install CD or Network.

2. Mount the Parent boot environment root slice to some directory (like
/mnt). You can use the following commands in sequence to mount the BE:

zpool import rpool
zfs inherit -r mountpoint rpool/ROOT/s10x_u9wos_14a
zfs set mountpoint= rpool/ROOT/s10x_u9wos_14a
zfs mount rpool/ROOT/s10x_u9wos_14a

3. Run utility with out any arguments from the Parent boot
environment root slice, as shown below:

/sbin/luactivate

4. luactivate, activates the previous working boot environment and
indicates the result.

5. Exit Single User mode and reboot the machine.

**********************************************************************

Modifying boot archive service
Propagating findroot GRUB for menu conversion.
File propagation successful
File propagation successful
File propagation successful
File propagation successful
Deleting stale GRUB loader from all BEs.
File deletion successful
File deletion successful
File deletion successful
Activation of boot environment successful.
root @ ktulhu / # lustatus
Boot Environment Is Active Active Can Copy
Name Complete Now On Reboot Delete Status
-------------------------- -------- ------ --------- ------ ----------
s10x_u9wos_14a yes yes no no -
s10x_u10wos_17b yes no yes no -

root @ ktulhu / # init 6
propagating updated GRUB menu
Saving existing file in top level dataset for BE as //boot/grub/menu.lst.prev.
File propagation successful
File propagation successful
File propagation successful
File propagation successful


Готово. Готово?

Нет. После перезапуска и активации мы обнаруживаем одну проблему.

Все наши гранты RBAC оказались утеряны. Часть сервисов (не системных) не стартует.

Разбираемся. Все просто -

/etc/security/prof_attr
/etc/security/exec_attr
/etc/user_attr

БЕЗ ПРЕДУПРЕЖДЕНИЯ И СОЗДАНИЯ БЭКАПА заменены дефолтными.

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

Я никак не комментирую ни наличие бага в LU, заставляющего нарушать правила и рекомендации при выполнении подобного апгрейда, ни вынос кастомных настроек RBAC (что, вообще говоря, недопустимо - Солярис уже много лет трепетно относится к конфигам при апгрейдах, предыдущий релиз корректно отрабатывает обновления конфигов - и либо их подхватывает, либо создает бэкапы, либо - если не может ни то ни другое, записывает новую версию рядом, для ручной замены администратором).

Просто запомните.

  1. Live Upgrade на update 10 должен выполняться с использованием пакетов начального релиза 9/10.
  2. ПЕРЕД обновлением сохраните ваши конфигурации RBAC.

пятница, 16 сентября 2011 г.

Как удалить 1,5 миллиона файлов?

Вопрос, вынесенный в заголовок, недавно встал во весь рост довольно-таки приличной проблемой. 

Преамбула.

Есть почтовый сервер, который плодит в большом количестве мелкие логи сообщений и событий. Этот сервер установлен на раздел UFS, на котором внезапно кончаются inodes. Задолго до исчерпания, собственно, объема раздела. Как следствие, почтовик перестал нормально функционировать.

Задача - нужно удалить эти полтора миллиона мелких файлов (не более 1-4 Кб) с раздела, дабы сервер мог продолжать свою работу.

Проблема в следующем. Файлы лежат в одной директории. Если вы попытаетесь просто сделать ls - два часа ожидания. Пытаетесь сделать rm -f * из bash - segmentation fault. Пытаетесь сделать то же самое из Борна - too many arguments. Пытаетесь удалить директорию - rm -R - несколько часов ожидания и результат не гарантирован.

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

Как решить проблему?

На UFS есть трюковый ход. 

unlink имя_директории

Три секунды и все. Директория со всем содержимым удалена, файлов нет, создаем директорию заново и даем на нее прежние права.

ВНИМАНИЕ! Не пытайтесь повторить это дома! В случае ошибки любая директория, включая системную, будет удалена со всем содержимым мгновенно и безвозвратно!

Имейте в виду. Данный прием работает ТОЛЬКО на ufs.

На zfs вы получите сообщение not owner:

root @ ktulhu /data # mkdir test
root @ ktulhu /data # unlink test
unlink: Not owner


Кстати, удаление директории с очень большим количеством файлов будет длительным на zfs тоже, несмотря на кэширование и все остальное. Более того, на zfs, с ее CoW, удаление может замедлиться в еще большей степени при сильном заполнении пула/датасета.

Мораль проста. Не плодите большого количества файлов в одной директории. Большинство ОС просто не рассчитаны на это. Кстати, приложения, работающие с файлами, тоже могут серьезно тормозить при доступе к таким директориям.

вторник, 6 сентября 2011 г.

Если бы строители строили свои дома, как программисты пишут свои программы...

... первый залетевший дятел разрушил бы цивилизацию.

Вот оно и свершилось, мальчики и девочки. Вот тебе раз. Вот тебе два. А вот тебе и три. Как неоднократно было сказано многими людьми, система доверия SSL CA порочна по сути. Стоит скомпрометировать один CA - и вся система в коллапсе. Последняя новость особенно леденящая душу.

Ну, где же CPS* DigiNotar? В котором написано английским по-белому - "Мамой клянусь, базовая инфраструктура PKI отделена от Интернета воздушным промежутком!"? Где эти писульки всех остальных CA, затронутых инцидентом?
_________________________________
* CPS - Certificate Policy and Certification Practice Statement

Насколько я помню, невозможно было стать CA/RA без выполнения ряда жесточайших условий, проверяемых рядом независимых аудитов, что никакое действие с приватным ключом CA невозможно выполнить менее, чем двумя людьми (separation of duty) и без полного журналирования действий, включая видеоконтроль, записи которого должны храниться три года, что ведутся логи всего и вся, что эти логи хранятся три и более года. Что проводятся периодические аудиты на соответствие высокому званию CA, что, в случае обнаружения несоответствий, удостоверяющий центр лишается права выдачи сертификатов. И многое-многое другое, масса красивых слов, декларируемых на бумажке, именуемой CPS, которые выложены на главных страницах CA и, самое главное, свято принимаемыми на веру всеми потребителями ЭЦП, увероваших в непогрешимость CA почти как в бога.

Где все эти меры? Хакнули CA - и все тут. Теперь вперед, отзови-ка все дерево сертификатов. Посредством CRL объемом этак гигабайт в сто. И, главное - сделайте это оперативно, ок? OCSP так и не заработал, и повсеместной практикой не стал.

Гром-то не гремел ни разу серьезно. До недавнего времени. Когда SSL стал мэйнстримом (слово-то какое отвратительное, суется где надо и где не надо). Кстати, в непогрешимом Линуксе тоже десятками посыпались критичные баги, едва он вылез в мэйнстрим, но это уже отдельная голубая печаль.

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

А к тому, что нам предлагают как панацею от Каминского и Ко DNSSEC. Который - ВНЕЗАПНО! - базируется не на чем ином, как на SSL. 

Ага. Снова CA, RA, деревья доверия. Доверия кому? CA? CPS? "Мамой клянемся, что свято выполняем заветы Брюса Шнайера и у нас мышь не проползет"?

Причем - что самое характерное - никто не понял, что Пушистый Пушной Зверек, собственно, уже подкрался. Что скомпрометированы все смежные технологии, прямо или косвенно использующие SSL - например, SSH. Что под фактическим ударом оказались все интернет-банкинги, гнущие пальцы, что "ваши транзакции надежно защищены".  Что коллапс деревьев доверия начался и лавину не остановить. Что надо запасаться попкорном и ждать следующей серии инцидентов с причинением ущерба в крупном и особо крупном размере.

Я не буду повторяться, цитировать Брюса или Ричарда. Незачем. Понимающему и так достаточно.

Я лишь хочу сказать снова и снова - понятия "безопасность" и "доверие" ортогональны. Хотите вы этого, или нет.

понедельник, 22 августа 2011 г.

Не нужно апгрейдить ZFS root pool!

Недавно мне довелось нарваться на совершенно феерическую засаду с обновлениями Solaris. История вышла более, чем поучительная. Как известно, я люблю ставить сервера в режим необслуживания. То есть вывешивать все рутинные задачи в cron и спокойно заниматься своими делами, время от времени получая по почте уведомления о выполнении этих самых рутинных задач.

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

Один из серверов обновлялся по регулярному графику, раз в месяц. Прошла группа обновлений. И тут мне пришло в голову заглянуть на его дисковую систему. Первое, что кинулось в глаза:

root @ hostname / # zpool status rpool
pool: rpool
state: ONLINE
status: The pool is formatted using an older on-disk format. The pool can
still be used, but some features are unavailable.
action: Upgrade the pool using 'zpool upgrade'. Once this is done, the
pool will no longer be accessible on older software versions.
scan: scrub repaired 0 in 0h5m with 0 errors on Sat Aug 20 06:05:03 2011
config:

NAME STATE READ WRITE CKSUM
rpool ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
c1t0d0s0 ONLINE 0 0 0
c1t1d0s0 ONLINE 0 0 0

errors: No known data errors


"Ого!" - сказали мужики. Непорядок. Надо обновить. Сделал, как сказано. И оставил все на своих местах.

И тут, пару недель спустя, пришла пора другого обновления. Обновление прошло, надо перезагрузиться. Перезагружаю сервер. Упс! Не стартует. Вылетает в меню GRUB и ни шагу дальше. Нет кернела. То есть как нет кернела?!

Первое и естественное действие - взять дистрибутивный DVD и стартовать с него в single user shell. Опачки - не видит установленной ОС. Совсем.

Хорошо, импортирую пулы. Пулы не импортируются. Сообщение об ошибке - "Файловая система слишком новой версии и не может быть импортирована".

Все страньше и страньше. Окей, беру LiveUSB Solaris 11. Гружусь. Импортирую пулы. Пулы импортируются. Однако теперь формат ZFS слишком старый. Заглядываю в импортированный корневой пул. Вижу только /boot и /etc. Причем /etc какой-то не полный. zfs list показывает все компоненты корневого пула, заполнение правильное, все на месте - swap, dump, var. Но в точке монтирования кроме двух указанных директорий ничего.

Смотрю версии пулов. Версия пула на дисках 29. Версия пула Solaris 11 - 31я. Версия пулов в дистрибутиве (9/10) - 22. В голову приходит, что апгрейд до 31 версии приведет к тому, что ни туда ни сюда - диски уже не увидятся системой. В дистрибутиве версия пулов уже слишком старая. В 11й - слишком новая. Файлсэйф тоже, разумеется, не стартует. 

Приходит мысль, что при обновлении каким-то образом потерялся загрузчик. Записываю GRUB заново на оба диска с Solaris 11. Перезагрузка. Система наконец выводит меню загрузки..... стартует ядро.... паника, рестарт. Снова загрузка, старт ядра, паника, рестарт.

"Ага!" - сказали мужики. Выхода нет, надо восстанавливаться. Бэкап, восстановление, разбор полетов.

Итак, обновление ядра 144501-19. Меняется on-disk format ZFS. Первое и естественное желание - воспользоваться новыми фишками и апгрейдить ФС. Так вот, делать этого на корневом пуле НЕ НУЖНО.

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

Как было сказано в одном саппортном документе, не обновляйте корневой пул - пусть это сделает Oracle (вольный перевод). Лучше всего выполнять обновление корневого пула - с выходом нового релиза ОС, и не раньше. Дабы можно было его увидеть в случае чего, стартовав с дистрибутивного образа.

Мораль этой истории проста. Don't be in such a hurry - Горячки не порите.

воскресенье, 15 мая 2011 г.

Не болтай!

Хотите начистоту? Мое мнение совершенно неполиткорректно. 95% населения - клинические идиоты. Полные. Уже пальцы до крови стер и язык - писать и говорить об этом.

Совершенно свежий пример "честного человека, которому нечего скрывать" - надо же! - оказался с сыном Касперского. Который слишком много ВКонтакте написал о себе. Матерый ГБшник плохо воспитал своего сына в духе своей конторы. Даже не смог внушить мысль, что болтать о себе на публике надо поменьше, а слушать побольше. Результат немного предсказуем. Ну, и что, что оперативно убрали персональную информацию со страницы? Веб-архив уже не функционирует? Эффект Стрейзанд не действует?

Что, не впечатляет? Все еще не подействовало? Сколько раз должен клюнуть жареный петух к нижние 90, чтобы дошло?
Другой, не менее показательный пример - желание господина Павла Дурова волевым решением открыть закрытые страницы пользователей. При том, что удалить аккаунт влегкую нельзя и, ввиду уже упомянутых выше веб-архива и эффекта Стрейзанд - мало эффективно.

Пишите больше о себе, господа, пишите! Радарикс, хвала богам, таки умер, но его с легкостью заменит Гугл и Яндекс.

Облака и социальные сети - страшное зло, по моему личному убеждению. Невозможность физически проконтролировать что-либо, отсутствие достоверной и надежной защиты данных от третьих лиц (я, разумеется, имею в виду хоть сколько-нибудь приличное шифрование) , в сочетании с этим пресловутым "Мамой клянусь!" из пользовательских соглашений - милейшая вещь, согласитесь.

Но вы продолжайте верить, господа. "Блажен, кто верует". Общение и социализация важнее любой приватности. Что вообще такое прайвиси? Так, абстракция. Социализация, без сомнения, заменит ее. Живите дальше в своем стеклянном доме, где каждый человек - зажженая свечка.

воскресенье, 20 февраля 2011 г.

Squid + ClamAV + Squidclamav на Solaris 10

Меня достаточно давно терзала мысль, что неплохо было бы, в качестве первой линии обороны, прикрутить к Сквиду антивирусную проверку. Ясное дело, что транспарентный прокси не проверяет все и вся, однако если удастся сравнительно недорогой ценой проверять хотя бы HTTP-трафик на вирусы, то это будет неплохая первая линия обороны.

Итак, длительное исследование показало, что традиционная связка Squid + ICAP + ClamAV не получается по причине того, что c-ICAP не удается собрать на Солярисе. Никакими ухищрениями. И это тоже не получилось.

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

И тут на глаза попался Squidclamav.

Попробуем поженить эту связку.

Для начала нужно установить ClamAV. Берем его на родном сайте, не забываем, что у него есть зависимости - bzip2, libtool, ncurses и zlib. Зависимости берем на Sunfreeware.

Собираем. Конфигурируем:

clamd.conf


##
## Example config file for the Clam AV daemon
## Please read the clamd.conf(5) manual before editing this file.
##


# Comment or remove the line below.
#Example

# Uncomment this option to enable logging.
# LogFile must be writable for the user running daemon.
# A full path is required.
# Default: disabled
LogFile /tmp/clamd.log

# By default the log file is locked for writing - the lock protects against
# running clamd multiple times (if want to run another clamd, please
# copy the configuration file, change the LogFile variable, and run
# the daemon with --config-file option).
# This option disables log file locking.
# Default: no
LogFileUnlock yes

# Maximum size of the log file.
# Value of 0 disables the limit.
# You may use 'M' or 'm' for megabytes (1M = 1m = 1048576 bytes)
# and 'K' or 'k' for kilobytes (1K = 1k = 1024 bytes). To specify the size
# in bytes just don't use modifiers.
# Default: 1M
LogFileMaxSize 2M

# Log time with each message.
# Default: no
#LogTime yes

# Also log clean files. Useful in debugging but drastically increases the
# log size.
# Default: no
#LogClean yes

# Use system logger (can work together with LogFile).
# Default: no
LogSyslog yes

# Specify the type of syslog messages - please refer to 'man syslog'
# for facility names.
# Default: LOG_LOCAL6
#LogFacility LOG_MAIL

# Enable verbose logging.
# Default: no
#LogVerbose yes

# Log additional information about the infected file, such as its
# size and hash, together with the virus name.
ExtendedDetectionInfo yes

# This option allows you to save a process identifier of the listening
# daemon (main thread).
# Default: disabled
#PidFile /var/run/clamd.pid

# Optional path to the global temporary directory.
# Default: system specific (usually /tmp or /var/tmp).
TemporaryDirectory /tmp

# Path to the database directory.
# Default: hardcoded (depends on installation options)
#DatabaseDirectory /usr/local/clamav/lib

# Only load the official signatures published by the ClamAV project.
# Default: no
#OfficialDatabaseOnly no

# The daemon can work in local mode, network mode or both.
# Due to security reasons we recommend the local mode.

# Path to a local socket file the daemon will listen on.
# Default: disabled (must be specified by a user)
LocalSocket /tmp/clamd.socket

# Sets the group ownership on the unix socket.
# Default: disabled (the primary group of the user running clamd)
#LocalSocketGroup virusgroup

# Sets the permissions on the unix socket to the specified mode.
# Default: disabled (socket is world accessible)
#LocalSocketMode 660

# Remove stale socket after unclean shutdown.
# Default: yes
#FixStaleSocket yes

# TCP port address.
# Default: no
TCPSocket 3310

# TCP address.
# By default we bind to INADDR_ANY, probably not wise.
# Enable the following to provide some degree of protection
# from the outside world.
# Default: no
TCPAddr 127.0.0.1

# Maximum length the queue of pending connections may grow to.
# Default: 200
#MaxConnectionQueueLength 30

# Clamd uses FTP-like protocol to receive data from remote clients.
# If you are using clamav-milter to balance load between remote clamd daemons
# on firewall servers you may need to tune the options below.

# Close the connection when the data size limit is exceeded.
# The value should match your MTA's limit for a maximum attachment size.
# Default: 25M
#StreamMaxLength 10M

# Limit port range.
# Default: 1024
#StreamMinPort 30000
# Default: 2048
#StreamMaxPort 32000

# Maximum number of threads running at the same time.
# Default: 10
MaxThreads 20

# Waiting for data from a client socket will timeout after this time (seconds).
# Value of 0 disables the timeout.
# Default: 120
#ReadTimeout 300

# This option specifies the time (in seconds) after which clamd should
# timeout if a client doesn't provide any initial command after connecting.
# Default: 5
#CommandReadTimeout 5

# This option specifies how long to wait (in miliseconds) if the send buffer is full.
# Keep this value low to prevent clamd hanging
#
# Default: 500
#SendBufTimeout 200

# Maximum number of queued items (including those being processed by MaxThreads threads)
# It is recommended to have this value at least twice MaxThreads if possible.
# WARNING: you shouldn't increase this too much to avoid running out  of file descriptors,
# the following condition should hold:
# MaxThreads*MaxRecursion + (MaxQueue - MaxThreads) + 6< RLIMIT_NOFILE (usual max is 1024)
#
# Default: 100
#MaxQueue 200

# Waiting for a new job will timeout after this time (seconds).
# Default: 30
#IdleTimeout 60

# Don't scan files and directories matching regex
# This directive can be used multiple times
# Default: scan all
#ExcludePath ^/proc/
#ExcludePath ^/sys/

# Maximum depth directories are scanned at.
# Default: 15
MaxDirectoryRecursion 20

# Follow directory symlinks.
# Default: no
FollowDirectorySymlinks yes

# Follow regular file symlinks.
# Default: no
FollowFileSymlinks yes

# Scan files and directories on other filesystems.
# Default: yes
CrossFilesystems yes

# Perform a database check.
# Default: 600 (10 min)
#SelfCheck 600

# Execute a command when virus is found. In the command string %v will
# be replaced with the virus name.
# Default: no
#VirusEvent /usr/local/bin/send_sms 123456789 "VIRUS ALERT: %v"

# Run as another user (clamd must be started by root for this option to work)
# Default: don't drop privileges
#User clamav

# Initialize supplementary group access (clamd must be started by root).
# Default: no
#AllowSupplementaryGroups no

# Stop daemon when libclamav reports out of memory condition.
#ExitOnOOM yes

# Don't fork into background.
# Default: no
#Foreground yes

# Enable debug messages in libclamav.
# Default: no
#Debug yes

# Do not remove temporary files (for debug purposes).
# Default: no
#LeaveTemporaryFiles yes

# Detect Possibly Unwanted Applications.
# Default: no
#DetectPUA yes

# Exclude a specific PUA category. This directive can be used multiple times.
# See http://www.clamav.net/support/pua for the complete list of PUA
# categories.
# Default: Load all categories (if DetectPUA is activated)
#ExcludePUA NetTool
#ExcludePUA PWTool

# Only include a specific PUA category. This directive can be used multiple
# times.
# Default: Load all categories (if DetectPUA is activated)
#IncludePUA Spy
#IncludePUA Scanner
#IncludePUA RAT

# In some cases (eg. complex malware, exploits in graphic files, and others),
# ClamAV uses special algorithms to provide accurate detection. This option
# controls the algorithmic detection.
# Default: yes
#AlgorithmicDetection yes


##
## Executable files
##

# PE stands for Portable Executable - it's an executable file format used
# in all 32 and 64-bit versions of Windows operating systems. This option allows
# ClamAV to perform a deeper analysis of executable files and it's also
# required for decompression of popular executable packers such as UPX, FSG,
# and Petite.
# Default: yes
#ScanPE yes

# Executable and Linking Format is a standard format for UN*X executables.
# This option allows you to control the scanning of ELF files.
# Default: yes
#ScanELF yes

# With this option clamav will try to detect broken executables (both PE and
# ELF) and mark them as Broken.Executable.
# Default: no
#DetectBrokenExecutables yes


##
## Documents
##

# This option enables scanning of OLE2 files, such as Microsoft Office
# documents and .msi files.
# Default: yes
#ScanOLE2 yes


# With this option enabled OLE2 files with VBA macros, which were not
# detected by signatures will be marked as "Heuristics.OLE2.ContainsMacros".
# Default: no
#OLE2BlockMacros no

# This option enables scanning within PDF files.
# Default: yes
#ScanPDF yes


##
## Mail files
##

# Enable internal e-mail scanner.
# Default: yes
#ScanMail yes

# Scan RFC1341 messages split over many emails.
# You will need to periodically clean up $TemporaryDirectory/clamav-partial directory.
# WARNING: This option may open your system to a DoS attack.
#       Never use it on loaded servers.
# Default: no
#ScanPartialMessages yes


# With this option enabled ClamAV will try to detect phishing attempts by using
# signatures.
# Default: yes
#PhishingSignatures yes

# Scan URLs found in mails for phishing attempts using heuristics.
# Default: yes
#PhishingScanURLs yes

# Always block SSL mismatches in URLs, even if the URL isn't in the database.
# This can lead to false positives.
#
# Default: no
#PhishingAlwaysBlockSSLMismatch no

# Always block cloaked URLs, even if URL isn't in database.
# This can lead to false positives.
#
# Default: no
#PhishingAlwaysBlockCloak no

# Allow heuristic match to take precedence.
# When enabled, if a heuristic scan (such as phishingScan) detects
# a possible virus/phish it will stop scan immediately. Recommended, saves CPU
# scan-time.
# When disabled, virus/phish detected by heuristic scans will be reported only at
# the end of a scan. If an archive contains both a heuristically detected
# virus/phish, and a real malware, the real malware will be reported
#
# Keep this disabled if you intend to handle "*.Heuristics.*" viruses
# differently from "real" malware.
# If a non-heuristically-detected virus (signature-based) is found first,
# the scan is interrupted immediately, regardless of this config option.
#
# Default: no
#HeuristicScanPrecedence yes

##
## Data Loss Prevention (DLP)
##

# Enable the DLP module
# Default: No
#StructuredDataDetection yes

# This option sets the lowest number of Credit Card numbers found in a file
# to generate a detect.
# Default: 3
#StructuredMinCreditCardCount 5

# This option sets the lowest number of Social Security Numbers found
# in a file to generate a detect.
# Default: 3
#StructuredMinSSNCount 5

# With this option enabled the DLP module will search for valid
# SSNs formatted as xxx-yy-zzzz
# Default: yes
#StructuredSSNFormatNormal yes

# With this option enabled the DLP module will search for valid
# SSNs formatted as xxxyyzzzz
# Default: no
#StructuredSSNFormatStripped yes


##
## HTML
##

# Perform HTML normalisation and decryption of MS Script Encoder code.
# Default: yes
#ScanHTML yes


##
## Archives
##

# ClamAV can scan within archives and compressed files.
# Default: yes
#ScanArchive yes

# Mark encrypted archives as viruses (Encrypted.Zip, Encrypted.RAR).
# Default: no
#ArchiveBlockEncrypted no


##
## Limits
##

# The options below protect your system against Denial of Service attacks
# using archive bombs.

# This option sets the maximum amount of data to be scanned for each input file.
# Archives and other containers are recursively extracted and scanned up to this
# value.
# Value of 0 disables the limit
# Note: disabling this limit or setting it too high may result in severe damage
# to the system.
# Default: 100M
#MaxScanSize 150M

# Files larger than this limit won't be scanned. Affects the input file itself
# as well as files contained inside it (when the input file is an archive, a
# document or some other kind of container).
# Value of 0 disables the limit.
# Note: disabling this limit or setting it too high may result in severe damage
# to the system.
# Default: 25M
#MaxFileSize 30M

# Nested archives are scanned recursively, e.g. if a Zip archive contains a RAR
# file, all files within it will also be scanned. This options specifies how
# deeply the process should be continued.
# Note: setting this limit too high may result in severe damage to the system.
# Default: 16
#MaxRecursion 10

# Number of files to be scanned within an archive, a document, or any other
# container file.
# Value of 0 disables the limit.
# Note: disabling this limit or setting it too high may result in severe damage
# to the system.
# Default: 10000
#MaxFiles 15000


##
## Clamuko settings
##

# Enable Clamuko. Dazuko must be configured and running. Clamuko supports
# both Dazuko (/dev/dazuko) and DazukoFS (/dev/dazukofs.ctrl). DazukoFS
# is the preferred option. For more information please visit www.dazuko.org
# Default: no
#ClamukoScanOnAccess yes

# The number of scanner threads that will be started (DazukoFS only).
# Having multiple scanner threads allows Clamuko to serve multiple
# processes simultaneously. This is particularly beneficial on SMP machines.
# Default: 3
#ClamukoScannerCount 3

# Don't scan files larger than ClamukoMaxFileSize
# Value of 0 disables the limit.
# Default: 5M
#ClamukoMaxFileSize 10M

# Set access mask for Clamuko (Dazuko only).
# Default: no
#ClamukoScanOnOpen yes
#ClamukoScanOnClose yes
#ClamukoScanOnExec yes

# Set the include paths (all files inside them will be scanned). You can have
# multiple ClamukoIncludePath directives but each directory must be added
# in a seperate line. (Dazuko only)
# Default: disabled
#ClamukoIncludePath /home
#ClamukoIncludePath /students

# Set the exclude paths. All subdirectories are also excluded. (Dazuko only)
# Default: disabled
#ClamukoExcludePath /home/bofh

# With this option enabled ClamAV will load bytecode from the database.
# It is highly recommended you keep this option on, otherwise you'll miss detections for many new viruses.
# Default: yes
#Bytecode yes

# Set bytecode security level.
# Possible values:
#       None - no security at all, meant for debugging. DO NOT USE THIS ON PRODUCTION SYSTEMS
#         This value is only available if clamav was built with --enable-debug!
#       TrustSigned - trust bytecode loaded from signed .c[lv]d files,
#                insert runtime safety checks for bytecode loaded from other sources
#       Paranoid - don't trust any bytecode, insert runtime checks for all
# Recommended: TrustSigned, because bytecode in .cvd files already has these checks
# Note that by default only signed bytecode is loaded, currently you can only
# load unsigned bytecode in --enable-debug mode.
#
# Default: TrustSigned
#BytecodeSecurity TrustSigned

# Set bytecode timeout in miliseconds.
#
# Default: 5000
# BytecodeTimeout 1000


freshclam.conf

##
## Example config file for freshclam
## Please read the freshclam.conf(5) manual before editing this file.
##


# Path to the database directory.
# WARNING: It must match clamd.conf's directive!
# Default: hardcoded (depends on installation options)
#DatabaseDirectory /var/lib/clamav

# Path to the log file (make sure it has proper permissions)
# Default: disabled
UpdateLogFile /var/log/freshclam.log

# Maximum size of the log file.
# Value of 0 disables the limit.
# You may use 'M' or 'm' for megabytes (1M = 1m = 1048576 bytes)
# and 'K' or 'k' for kilobytes (1K = 1k = 1024 bytes).
# in bytes just don't use modifiers.
# Default: 1M
LogFileMaxSize 2M

# Log time with each message.
# Default: no
#LogTime yes

# Enable verbose logging.
# Default: no
#LogVerbose yes

# Use system logger (can work together with UpdateLogFile).
# Default: no
LogSyslog yes

# Specify the type of syslog messages - please refer to 'man syslog'
# for facility names.
# Default: LOG_LOCAL6
#LogFacility LOG_MAIL

# This option allows you to save the process identifier of the daemon
# Default: disabled
PidFile /var/run/freshclam.pid

# By default when started freshclam drops privileges and switches to the
# "clamav" user. This directive allows you to change the database owner.
# Default: clamav (may depend on installation options)
DatabaseOwner clamav

# Initialize supplementary group access (freshclam must be started by root).
# Default: no
#AllowSupplementaryGroups yes

# Use DNS to verify virus database version. Freshclam uses DNS TXT records
# to verify database and software versions. With this directive you can change
# the database verification domain.
# WARNING: Do not touch it unless you're configuring freshclam to use your
# own database verification domain.
# Default: current.cvd.clamav.net
#DNSDatabaseInfo current.cvd.clamav.net

# Uncomment the following line and replace XY with your country
# code. See http://www.iana.org/cctld/cctld-whois.htm for the full list.
# You can use db.XY.ipv6.clamav.net for IPv6 connections.
#DatabaseMirror db.XY.clamav.net

# database.clamav.net is a round-robin record which points to our most
# reliable mirrors. It's used as a fall back in case db.XY.clamav.net is
# not working. DO NOT TOUCH the following line unless you know what you
# are doing.
DatabaseMirror database.clamav.net

# How many attempts to make before giving up.
# Default: 3 (per mirror)
#MaxAttempts 5

# With this option you can control scripted updates. It's highly recommended
# to keep it enabled.
# Default: yes
#ScriptedUpdates yes

# By default freshclam will keep the local databases (.cld) uncompressed to
# make their handling faster. With this option you can enable the compression;
# the change will take effect with the next database update.
# Default: no
#CompressLocalDatabase no

# With this option you can provide custom sources (http:// or file://) for
# database files. This option can be used multiple times.
# Default: no custom URLs
#DatabaseCustomURL http://myserver.com/mysigs.ndb
#DatabaseCustomURL file:///mnt/nfs/local.hdb

# Number of database checks per day.
# Default: 12 (every two hours)
#Checks 24

# Proxy settings
# Default: disabled
#HTTPProxyServer myproxy.com
#HTTPProxyPort 1234
#HTTPProxyUsername myusername
#HTTPProxyPassword mypass

# If your servers are behind a firewall/proxy which applies User-Agent
# filtering you can use this option to force the use of a different
# User-Agent header.
# Default: clamav/version_number
#HTTPUserAgent SomeUserAgentIdString

# Use aaa.bbb.ccc.ddd as client address for downloading databases. Useful for
# multi-homed systems.
# Default: Use OS'es default outgoing IP address.
#LocalIPAddress aaa.bbb.ccc.ddd

# Send the RELOAD command to clamd.
# Default: no
NotifyClamd /usr/local/clamav/etc/clamd.conf

# Run command after successful database update.
# Default: disabled
#OnUpdateExecute command

# Run command when database update process fails.
# Default: disabled
#OnErrorExecute command

# Run command when freshclam reports outdated version.
# In the command string %v will be replaced by the new version number.
# Default: disabled
#OnOutdatedExecute command

# Don't fork into background.
# Default: no
#Foreground yes

# Enable debug messages in libclamav.
# Default: no
#Debug yes

# Timeout in seconds when connecting to database server.
# Default: 30
#ConnectTimeout 60

# Timeout in seconds when reading from database server.
# Default: 30
#ReceiveTimeout 60

# With this option enabled, freshclam will attempt to load new
# databases into memory to make sure they are properly handled
# by libclamav before replacing the old ones.
# Default: yes
#TestDatabases yes

# When enabled freshclam will submit statistics to the ClamAV Project about
# the latest virus detections in your environment. The ClamAV maintainers
# will then use this data to determine what types of malware are the most
# detected in the field and in what geographic area they are.
# Freshclam will connect to clamd in order to get recent statistics.
# Default: no
#SubmitDetectionStats /path/to/clamd.conf

# Country of origin of malware/detection statistics (for statistical
# purposes only). The statistics collector at ClamAV.net will look up
# your IP address to determine the geographical origin of the malware
# reported by your installation. If this installation is mainly used to
# scan data which comes from a different location, please enable this
# option and enter a two-letter code (see http://www.iana.org/domains/root/db/)
# of the country of origin.
# Default: disabled
#DetectionStatsCountry country-code

# This option enables support for our "Personal Statistics" service.
# When this option is enabled, the information on malware detected by
# your clamd installation is made available to you through our website.
# To get your HostID, log on http://www.stats.clamav.net and add a new
# host to your host list. Once you have the HostID, uncomment this option
# and paste the HostID here. As soon as your freshclam starts submitting
# information to our stats collecting service, you will be able to view
# the statistics of this clamd installation by logging into
# http://www.stats.clamav.net with the same credentials you used to
# generate the HostID. For more information refer to:
# http://www.clamav.net/support/faq/faq-cctts/
# This feature requires SubmitDetectionStats to be enabled.
# Default: disabled
#DetectionStatsHostID unique-id

# This option enables support for Google Safe Browsing. When activated for
# the first time, freshclam will download a new database file (safebrowsing.cvd)
# which will be automatically loaded by clamd and clamscan during the next
# reload, provided that the heuristic phishing detection is turned on. This
# database includes information about websites that may be phishing sites or
# possible sources of malware. When using this option, it's mandatory to run
# freshclam at least every 30 minutes.
# Freshclam uses the ClamAV's mirror infrastructure to distribute the
# database and its updates but all the contents are provided under Google's
# terms of use. See http://code.google.com/support/bin/answer.py?answer=70015
# and http://safebrowsing.clamav.net for more information.
# Default: disabled
#SafeBrowsing yes

# This option enables downloading of bytecode.cvd, which includes additional
# detection mechanisms and improvements to the ClamAV engine.
# Default: enabled
#Bytecode yes


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

Теперь нам надо поставить демон clamd в автозапуск SMF. Для этого напишем запускной скрипт и сервисный манифест. Это достаточно тривиальная процедура, поэтому детали я опускаю. Как результат наших действий получаем FMRI clamav и запускаем демон командой svcadm enable clamav.

Кроме того, поставим в cron запись для ежедневного обновления вирусных баз и оффлайнового сканирования кэша (как оказалось в дальнейшем, это не лишне делать):


# ClamAV database update job. Running daily at 00:00
0 0 * * * [ -x /usr/local/clamav/bin/freshclam ] && /usr/local/clamav/bin/freshclam --quiet

# ClamAV offline data pool scan job. Running daily at 2:00
0 2 * * * [ -x /usr/local/clamav/bin/clamscan ] && /usr/local/clamav/bin/clamscan -r -i --remove=yes /data/cache

Теперь необходимо собрать squidclamav. Первое, о чем надо позаботиться - о версии и зависимостях. О которых никто не удосужился написать в readme. Для squidclamav это curl. Который, в свою очередь, тащит за собой серию других зависимостей. Это, в общем, достаточно самоочевидная зависимость, однако выясняется это только при сборке.

Update от 10.08.2011
______________________________________________________

1. Версия SquidClamAV, которая поддерживается на Solaris - 5.7. Это важно. Шестая ветка рассчитана исключительно на использование iCAP и на Solaris не собирается.
2. CURL, лежащий на Sunfreeware - битый, а точнее, собранный неправильно. С ним не собирается. Надо скачать исходники от авторов - отсюда, предварительно собрать ручками без поддержки SSH2 (она не нужна, но вызывает лишние проблемы при сборке SquidClamAV) с использованием Solaris Studio 12.
3. Сам SquidClamAV собрать GCC.
______________________________________________________

После сборки squidclamav можно приступать к конфигурированию.

Принцип следующий. Squidclamav - это редиректор, наподобие squidGuard, который может работать со squidGuard в цепочке. Причем ставится он первым в последовательности редиректоров сквида. При редиректе squidclamav отдает файл на проверку демону clamd, и, в зависимости от результата, либо редиректит пользователя на свою станицу, объясняющую, что в файле вирус, либо отдает URL для проверки дальше squidGuardу.

Тут есть одна тонкость. Проверка делается только после того, как файл скачивается и попадает в кэш. Если в нем вирус, отдача из кэша может быть заблокирована параметром trust_cache. Но при дефолтном значении на первую попытку получить файл squidclamav ругается, а на вторую и последующие все-таки отдает файл с вирусом. Технически редиректор выполняет PURGE при обнаружении вируса, однако практика показала, что часто вирус все-таки долетает до кэша, поэтому оффлайновый вызов clamscan раз в сутки совершенно не лишний (дабы кэш у нас оставался чистым).

При конфигурировании squidclamav нужно не забыть взять нужный вариант блокирующей страницы и положить ее в директорию cgi-bin настроенного на сквиде апача.

______________________________________________________

ВАЖНО! Дабы не поймать рекурсию при антивирусной проверке файлов Сквидом, необходимо добавить в конфиг сквида строчку:

# Rewriter cycle workaround
url_rewrite_access deny localhost

ПЕРЕД СТРОКОЙ:
# And finally deny all other access to this proxy
http_access deny all

______________________________________________________


Итак, финальная конфигурация squidclamav.

squidclamav.conf

#-----------------------------------------------------------------------------
# SquidClamav v5.3 default configuration file
#
# To know to customize your configuration file, see squidclamav manpage
# or go to http://squidclamav.darold.net/
#
#-----------------------------------------------------------------------------
#
# Global configuration
#
squid_ip 127.0.0.1
squid_port 3128
logfile /usr/local/squid/var/logs/squidclamav.log
maxsize 5000000
redirect http://localhost/cgi-bin/clwarn.cgi.ru_RU
squidguard /usr/local/bin/squidGuard
debug 0
stat 0
maxredir 96
clamd_local /tmp/clamd.socket
clamd_ip 127.0.0.1
clamd_port 3310
timeout 60
useragent Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)
trust_cache 0
logredir 0

#
# Squidclamav behaviour
# (since v5.0 Squidclamav scan all file by default)
#
# Here is the defaut regex pattern pattern I use to bypass virus scan.
#

# Do not scan images
abort ^.*\.(gif|png|jp?g|ico|bmp|tiff?)$
abortcontent ^image\/.*$

# Do not scan text files
abort ^.*\.(css|xml|xsl|js|html|jsp)$
abortcontent ^text\/.*$
abortcontent ^application\/x-javascript$

# Do not scan streamed videos
abortcontent ^video\/x-flv$
abortcontent ^video\/mp4$

# Do not scan flash files
abort ^.*\.swf$
abortcontent ^application\/x-shockwave-flash$

# Do not scan sequence of framed Microsoft Media Server (MMS) data packets
abortcontent ^.*application\/x-mms-framed.*$

# White list some sites
whitelist .*\.clamav.net

# See also 'trustuser' and 'trustclient' configuration directives


Количество редиректоров делаем таким же, как и количество процессов squidGuard, дабы не возникало узкого места. Параметр clamd_local должен иметь значение, совпадающее со значением LocalSocket из конфигурации clamd.conf, параметр trust_cache установим в 0, чтобы предотвратить отдачу вирусного файла из кэша клиенту при любых обстоятельствах.

Последнее, что необходимо сделать - это изменить rewriter в squid.conf:


# SquidGuard rewriter
#url_rewrite_program /usr/local/bin/squidGuard -c /usr/local/squidGuard/squidGuard.conf
# SquidClamAV rewriter
url_rewrite_program /usr/local/bin/squidclamav
url_rewrite_children 96
redirect_rewrites_host_header on
#redirector_bypass on

Собственно, это все. Осталось перезапустить сквида командой squid -k reconfigure и можно проверять связку по ссылке.

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