Cfengine - это инструмент автоматизации администрирования гетерогенных систем и *nix систем
Продолжаем знакомится с системой Cfengine
Понятие классов является основополагающей идее в работе cfengine. То, что работа cfengine основывается на понятии классов, означает, что он не принимает решений, используя конструкции ifthenelse так, как это делают другие языки.
Он выполняет действие только в том случае, если хост, на котором он запускается, принадлежит к тому же классу, что и само действие. Чтобы понять, что это значит, представим себе процесс выбора определённых хостов из общего списка всех хостов сайта. Допустим, что мы ищем такой класс хостов, которые принадлежали бы к вычислительному отделу, работали бы с операционной системой GNU/Linux и имели бы жёлтые пятна. Для того, чтобы определить удовлетворяет ли конкретный хост данным критериям, в первую очередь, нужно исключить из рассмотрения все хосты, работающие на операционных системах, отличных от GNU/Linux. Затем из числа оставшихся необходимо исключить не принадлежащие вычислительному отделу, а затем из оставшихся исключить хосты без жёлтых пятен. В оставшемся списке будут находиться хосты, удовлетворяющие всем критериям. Теперь над ними можно выполнять действия.
Cfengine работает подобным образом. Весь описанный выше процесс он сводит к проверке принадлежности хоста нескольким классам одновременно. Хотя определённая информация о хостах может быть получена напрямую (например, используемая операционная система), но очевидно, что для проверки остальных параметров необходимо иметь список хостов, принадлежащих к вычислительному отделу и список хостов с жёлтыми пятнами.
Как это осуществляется в программе cfengine? Программа или конфигурационный скрипт состоит из ряда объявлений, называемыми действиями (action), которые должны выполняться только для определённых классов хостов. Любой хост может запускать программу, но выполняться будет только то действие, которое соответствует данному конкретному хосту. Это происходит автоматически, поскольку cfengine создаёт список классов, которому принадлежит хост, в процессе работы, поэтому ему не приходиться снова и снова принимать большого числа решений.
Создание классов, которые классифицировали бы хосты системы неким простым для понимания путём, позволяет за один раз выполнять одно действие для нескольких хостов, причём только для тех, для которых нужно. Можно создавать классы, согласно определённому типу операционной системы, можно сгруппировать вместе кластеры и рабочие станции в зависимости от того, кто будет их использовать, также можно помечать их жёлтыми пятнами и многое многое другое.
Действие в cfengine выглядит примерно следующим образом:
action-type: (тип действия) compound-class:: (классы) declaration (объявления)
Класс может быть следующим:
Составной класс представляет собой последовательность простых классов, связанных точками или символом конвейеризации (вертикальные черточки). Наприме
myclass.sun4.Monday:: sun4|ultrix|osf::
Значение составного класса является истинным, если значение всех входящих в него простых классов является истинным. Таким образом, в рассмотренном примере действия, следующие после compound_class:: будут выполнены, если рассматриваемый хост принадлежит myclass, имеет тип sun4 и всё происходит в понедельник. Во втором примере, хост, на котором запущен файл, должен быть либо sun4, либо Ultrix, либо osf. Другими словами, составные классы поддерживают работу с двумя операторами AND (и) или OR (или), обозначаемыми . или | соответственно. Начиная cfengine версии 2.1.1. для оператора AND (и) также используется символ &. Cfengine не имеет ограничений на количество используемых операторов (поскольку он пропускает пустые имена классов), поэтому возможны разные формы записи:
solaris|irix:: или solaris||irix::
в зависимости от желания. С другой стороны, важен порядок записи операторов AND и OR.
Правило состоит в том, что AND имеет более высокий приоритет, чем OR. Поэтому . тесно связывает классы, и операторы OR будут исполнены только после того, как были выполнены все операции AND. Это характерно для всех языков программирования. Для изменения такого порядка необходимо использовать круглые скобки.Cfengine предоставляет возможность определять активные и неактивные временные (dummy) классы, что позволяет выбрать определённое подмножество действий. В частности, стоит заметить, что определяя собственные классы, используя их для создания составных правил данного типа, а затем включая и выключая их, также можно включить и выключить соответствующие действия контролируемым способом (in a controlled way). Для этого можно использовать опции командной строки D и N. См. addclasses в приложении к руководству.Оператор логического отрицания (NOT) был добавлен, чтобы позволить более удобным способом исключать определённые хосты. Оператор логического отрицания NOT, как и в C и C++, обозначается символом !. В следующем примере исключается хост с именем myhost:
action: !myhost:: command
аналогичным образом, следующий пример разрешает все хосты определённой пользователем группы mygroup за исключением myhost:
action: mygroup.!myhost:: command
что читается, как mygroup AND NOT myhost. Оператор NOT также можно сочетать с оператором OR. В примере class1|!class2 будут выбраны хосты, которые либо принадлежат классу class1 или не принадлежат классу class2.
Наконец, существует ряд зарезервированных классов. Приведённые ниже классы являются жёсткими для различных архитектур операционных систем. Их не нужно определять, так как каждый хост знает, какая операционная система на нём установлена. Таким образом, для каждого хоста всегда будет выбран один из них. По тем же причинам, очевидно, не нужно определять день недели, за исключением случая, когда cfengine запускается из космоса. Зарезервированными классами являются:
ultrix, sun4, sun3, hpux, hpux10, aix, solaris, osf, irix4, irix, irix64 sco, freebsd, netbsd, openbsd, bsd4_3, newsos, solarisx86, aos, nextstep, bsdos, linux, debian, cray, unix_sv, GnU, NT
Если данных классов недостаточно для различения хостов сети, то cfengine имеет ряд более специальных классов, которые содержат имя и релиз операционной системы. Чтобы понять, как это выглядит для конкретной системы, можно запустить cfengine в режиме parse-only-verbose (анализ-только-диалог):
cfagent -p v
и эта информация будет выведена. Например, системы Solaris 2.4. создают дополнительные классы sunos_5_4 и sunos_sun4m, sunos_sun4m_5_4.
В качестве имён классов cfengine использует как неуточнённые, так и полные имена хостов. Некоторые сайты и операционные системы для своих хостов используют полностью уточнённые имена, то есть uname n вернётся к полному доменному уточнённому имени хоста. Это вызывает неполадки в алгоритмах сопоставления классов cfengine, поэтому он автоматически сокращает имена, содержащие точку .до первой, с которой он встретится. Если имя хоста содержит точки (которые не относятся к доменному имени), то cfengine запутается. Отсюда вывод: имена хостов не должны содержать точек! Внимание: для того, чтобы бы убедиться, что полностью уточнённое имя хоста становится классом, необходимо определить переменную домена. Точки в этой строке будут заменены символами подчёркивания.
Приведём список операторов, которые можно использовать при работе с классами в cfengine:
При создании файла конфигурации очень удобно иметь возможность использовать переменные. Возможность определить конфигурацию с использованием некоторых ключевых переменных ключа, может упростить её редактирование в дальнейшем, сделать её более понятной для чтения, а также позволит по-разному определять переменные на различных типах систем. Другими словами, переменные в cfengine также принадлежат классам. В cfengine существует три направления использования переменных:
Переменные окружения получаются непосредственно из оболочки, на какой бы системе не запускалась программа. Примером специальной переменной является переменная domain предыдущего раздела. Прямая макро-замена позволяет определить символьное имя, которое следует заменить произвольной текстовой строкой. Все эти определения (естественно, за исключением переменных окружения shell) производятся в части control программы cfengine:
control: myvar = ( /usr/local/mydir/lib/very/long/path ) # define macro ... links: $(myvar) -> /another/directory
В данном примере определяется макро под названием myvar, которая в дальнейшем используется, чтобы обозначить создание ссылки. Также можно определять переменные, зависимые от классов:
control: sun4:: myvar = ( sun ) hpux:: myvar = ( HP )
Cfagent предоставляет доступ к переменным окружения shell и позволяет создавать собственные переменные. Он также имеет несколько специальных переменных, влияющих за его работу. При раскрытии переменной cfengine в первую очередь ищет такое имя в своём списке специальных переменных, затем в определённых пользователем макро-переменных и только потом среди переменных оболочки. Если соответствие так и не было установлено, он вернёт пустую строку. При вставке макро-переменных необходимо заключать правую часть в кавычки и убедиться, что значение уже определено:
control: myvar = ( "$(othervar)" )
Значения также можно вставлять из выполнения команд shell. Для этого перед командой необходимо поставить exec. Этот метод резко осуждается в версии 2 и был заменён функцией.
control: # old method listing = ( "exec /bin/ls -l" ) # new method listing = ( ExecResult(/bin/ls -l) )Это задаёт листинг переменных в вывод команды в ковычках.
Некоторые другие внутренние функции:
RandomInt(a,b) Выдаёт случайное число между a до b. ExectResult(command)
Выполняет заданную команду shell и записывает результат в переменную. Например:
control: variable2 = ( RandomInt(0,23) ) variable3 = ( ExecResult(/bin/ls -a /opt) )
В зависимости от желания к переменным можно обратиться двумя различными способами. Можно использовать формы $(переменная) или ${переменная}. Переменной в круглых или фигурных скобках может быть имя любого определённого пользователем макро, переменная окружения или одна из следующих специальных внутренних переменных.
AllClasses | Длинная строка вида CFALLCLASSES=class1:class2. Эта переменная является перечнем всех когда-либо определённых классов. Информация в ней постоянно обновляется для того, чтобы скрипты могли использовать данные о классах cfengine. |
Arch | Текущая детализироанная строка архитектуры, представляющая собой объединения всей информации из uname. Неопределяемая переменная. |
Binserver | Сервер, используемый по умолчанию, для двоичных данных. См. Раздел 4.6. [ресурсы NFS]. Неопределяемая переменная. |
class | Ныне определённый жёсткий класс системы (например, sun4, hpux). Неопределяемая переменная. |
date | Строка с текущей датой. Обратите внимание, что при её использовании в командах оболочки, она может быть проинтерпретирована как переменная списка, так как она по умолчанию содержит разделитель :. |
domain | Определённый в настоящее время домен |
faculty | Факультет или сайт, согласно определению в контроле (см. сайт) |
fqhost | Полностью уточнённое (DNS/BIND) хостимя системы, которое также включает доменное имя. |
Host | Хостимя машины, на которой запущена программа. |
Ipaddress | Интернет адрес хоста, на котором в данный момент работает cfengine, записанный в числовой форме. |
MaxCfengines | Максимальное число cfengine, которые могут одновременно сосуществовать в системе. Это позволяет предотвратить перегрузку из-за непреднамеренного спаминга в ситуации, когда несколько cfagent запускаются независимо друг от друга. Значение по умолчанию это количество неограниченно. |
ostype | Краткий вариант для $(arch) |
OutPrefix | Такую строку, записанную в двойных кавычках, можно использовать для
смены cfengine по умолчанию: префикс в выходных строках на что-то
другое. Возможно укоротить строку или установить разные префиксы для
разных хостов. К значению данной переменной также прибавляется имя
хоста. По умолчанию: OutputPrefix = ( cfengine:$(host): ) |
RepChar | Символьное значение строки, используемой файловым хранилищем в процессе создания уникальных файловых имён из имён пути. Такая строка заменяет символ /. (см. приложение к руководству) |
site | Эта переменная идентична $(faculty) и может употребляться вместо неё |
split | Признак, по которому разделяются переменные списка (см. приложение к руководству) |
sysadm | Имя или e-mail системного администратора |
Timezone | Текущая временная зона, определённая в control |
UnderscoreClasses | Если установлено значение on, то cfengine использует жёсткие классы, начинающиеся с символа нижнего подчёркивания, с целью избежать столкновения имён. Смотрите также опции Runtime в приложении к руководству. |
year |
текущий год |
Данные переменные определены, как специальные, потому что они играют особую роль в создании конфигурации системы, см. главу 4 [Глобальная конфигурация]. Их очень полезно использовать для задания полностью обобщённых правил в программе. Переменные также могут использоваться при определении имён файлов и директорий, а также для передачи аргументов командам оболочки. Разумное использование переменных может помочь свести множество определений в одно при тщательном планировании.
Внимание: перечисленные выше переменные управления не чувствительны к регистрам, в отличие от пользовательских макросов. Поэтому нельзя определять пользовательские макросы с этими именами.
Следующие переменные также являются зарезервированными и могут быть использованы для включения в строки специальных сложных символов.
cr |
символ возврата каретки |
dblquote |
символ двойных кавычек |
dollar | символ $ |
n | символ начала строки |
quote | единичная кавычка |
spc |
пустой символ. Он может быть использован, например, для вставки пробелов в именя файлов и т.д. |
tab | единичная табуляция |
Переменные модно использовать в следующих случаях:
links: osf:: /$(site)/${host}/directory -> somefile<!-- @page { size: 21cm 29.7cm; margin: 2cm } P { margin-bottom: 0.21cm } -->
shellcommands: any:: "/bin/echo $(timezone) | /bin/mail $(sysadm)" '/bin/echo "double quotes!"'
Переменные могут быть по-разному определены под разными классами, если перед определением поставить имя класса. Например:
control: sun4:: my_macro = ( User_string_1 ) irix:: my_macro = ( User_string_2 )
В данном примере значение, присваиваемое $(my_macro) зависит от того, на каком из классов будет выдано значение истины. Такая возможность может быть эффективно использована для задания mail адреса нужного системного администратора для разных групп хостов.
control: physics:: sysadm = ( mark,fred ) chemistry:: sysadm = ( localsys@domain )Обратите внимание, что опция -a может быть использована, чтобы вывести mail адрес системного администратора для любого вложенного скрипта.
Обратите внимание, что неопределённые макро-переменные не развёртываются на версии 1.6 cfengine. В более ранних версиях неопределённые переменные заменялись пустой строкой, как в Perl. Начиная с версий 1.6.x строка с переменной не заменяется, если переменной не существует. Например,control:
actionsequence = ( shellcommands )Это позволяет модулям определять переменные в процессе работы.
myvar = ( "test string " )
shellcommands:
"/bin/echo $(myvar) $(myvar2)"
results in:
cfengine:host: Executing script /bin/echo test string $(myvar2)
cfengine:host:/bin/echo test : sh: syntax error at line 1: `(' unexpected
cfengine:host: Finished script /bin/echo test string $(myvar2)
Cfengine говорит сам с собой, посылая сообщения в форме классов. Когда класс переходит во включенное или выключенное состояние, программа cfengine изменяется соответствующим образом. Существует несколько способов включения и выключения классов. Полное изучение этого механизма потребует времени, но только после этого станет возможным использовать в cfengine полную силу.
Классы можно определять вручную в командной строке
Классы можно определять локально в последовательности действий actionsequence для того, чтобы запускать только некоторые действия, относящиеся к отдельной категории.
Классы могут быть определены автоматически, если cfengine необходимо совершить какое-то действие для устранения неполадок в конфигурации системы.
Классы могут быть определены сменным модулем, заданным пользователем.
В связи с тем, что cfagent работает на очень высоком уровне, выполняя множество действий, соответствующих всего нескольким строкам кода, может показаться, что это сделано в ущерб гибкости. Когда некоторые действия приписываются специальным классам, то временами может оказаться удобным иметь возможность на время выключить классы, чтобы выключить специальные действия.
Можно самостоятельно определять классы, которые могут быть включены или выключены, как через командную строку, так и через последовательность действий action sequence. Например, определим класс include. Для этого используется addclasses.
addclasses = ( include что-то )
Целью такого создания позволить задавать действия, подлежащие исключению. Действия, определённые с помощью
any.include:: actions
будут выполняться при обычных обстоятельствах, поскольку с помощью addclasses мы определили значение include, как истинное. Но если cfagent запускается в ограниченном режиме, где значению include соответствует ложь, эти действия могут быть исключены.
Итак, присваивая символу include значение ложь, можно исключить все действия, которые в качестве своего члена содержат include. Это может быть сделано двумя способами. Один глобально проотрицать класс, используя
Cfagent N include.
Это исключает класс include на протяжении всей программы.
Другим способом определить действия является использование классов, чтобы выбрать только подмножество всех действий, заданных в actionsequence. Это можно сделать, добавив имя класса к одному из действий в последовательности действий, используя точку . для разделения слов. В таком случае символу будет присвоено значение истины на протяжении только того действия, к которому он был присоединён. Например:
links.onlysome shellcommands.othersymbols.onlysome
В первом случае onlysome будет истинным пока выполняется links. Это значит, что в результате такого задания выполняться будут только действия, отмеченные классом onlysome. В следующем примере как onlysome, так и othersymbols определены как истинные при выполнении shellcommands.
Такой синтаксис обычно используется для того, чтобы избежать определённых действий, требующих большого количества времени, например, чистка всех домашних папок. Также его можно использовать для синхронизации определённых действий, которые должны выполняться в определённом порядке.
Для более широкого использования возможностей cfengine, может возникнуть потребность определять классы, исходя из успешного или неуспешного выполнения пользовательской программы, команды shell или пользовательского скрипта. Рассмотрим следующий пример:
groups: have_cc = ( "/bin/test -f /usr/ucb/cc" "/bin/test -f /local/gnu/cc" )
Обратите внимание, что в версии cfengine 1.4.0 слово classes можно использовать в качестве алиаса для groups. Каждый раз, когда cfagent встречает объект в списке классов или переменной, заключённой в двойные, одинарные или обратные кавычки, он пытается исполнить такую строку, как команду, переданную Bourne shell. Если результирующая команда возвращает код нуля (означающий выход), тогда классу стоящему по левую сторону знака равно (в данном примере have_cc) присваивается значение истины. В случае, если команда вернула любое другое значение (номер ошибки) результатом будет ложь. Так как группы получаются с помощью операции логического ИЛИ их членов (достаточно, чтобы только один член принадлежал текущей системе), то класс have_cc в рассмотренном примере будет определён, если существует или /usr/ucb/cc, или /local/gnu/cc, или оба сразу.
Классы могут представлять собой результат действий, выполняемых cfagent. Например, можно настроить cfagent так, что при копировании файла, его редактировании или при нехватке пространства на диске из-за существующего ограничения, он ответит активацией классов в течение рабочего цикла. Это позволяет создавать программы, которые способны динамично отвечать, реагируя на изменения среды. Такие классы задаются как часть других предложений с основами в форме
define=classlist
Подобные классы, как правило, должны быть определены в начале программы, если только define не всегда предшествует действиям, которые используют созданные классы, с addinstallable.
В том случае, когда обычные механизмы создания классов не приводят к требуемым для конфигурации результатам, то существует возможность писать собственные программы для создания классов, отвечающих всем желаниям. Вспомогательные модули добавляются в программы cfagent внутри последовательности действий action sequence (см. приложение к руководству). Они позволяют создавать специальный код для решения задач, которые сложно решить с использованием других, рассмотренных ранее, механизмов. Это позволяет управлять классами, которые будут включены, и моментом, когда модуль будет пытаться оценить состояние системы.
Модули должны храниться в специальной папке, определённой переменной moduledirectory. Они должны иметь имя вида module:mymodule и должны следовать простому протоколу. Cfagent будет запускать модуль, принадлежащий либо корню, либо пользователю, запускающему cfagent, только если он находиться в специальной папке и под особым именем. Вспомогательный модуль может быть написан на любом языке и иметь любой вывод. Но строки, начинающиеся со знака + воспринимаются, как классы, которые должны быть определеными (как -D), тогда как начинающиеся с -, трактуются как классы, которые должны быть неопределёнными (как -N).
Строчки, начинающиеся с = являются переменными \ макросами, которые должны быть определёнными. Любые другие строки вывода размещаются cfagent, так что, как правило, модуль должен быть совершенно молчаливым. Ниже приведён пример модуля на Perl. В первую очередь определяется модуль в программе cfagent:
actionsequence = ( files module:myplugin "module:argplugin arg1 arg2" copy ) ... AddInstallables = ( specialclass )
Обратите внимание, что определения классов для модуля также должны быть заданы в AddInstallables, если так удобнее. Кроме того, необходимо запомнить, что классы необходимо объявлять до их использования в конфигурации cfagent, в противном случае такие действия будут пропущены. Теперь создаётся сам плагин:
#!/usr/bin/perl # # module:myplugin # # lots of computation.... if (special-condition) { print "+specialclass"; }
Модули получают переменные среды из cfagent и воспринимают аргументы также как и обычная команда shell.
#!/bin/sh # # module:myplugin # /bin/echo $*
Cfagent определяет классы как переменную окружения, так что программы имеют к ним доступ. Например, следующий модуль:
#!/usr/bin/perl print "Decoding $ENV{CFALLCLASSES}\n"; @allclasses = split (":","$ENV{CFALLCLASSES}"); while ($c=shift(@allclasses)) { $classes{$c} = 1; print "$c is set\n"; }
Модули могут определять макросы в cfagent, выводя строчки в форме
=variablename=value
Когда переменная $(allclasses) становиться слишком большой для удобной работы, доступ к списку всех созданных к текущему моменты классов можно получить в файле /var/cfengine/state/allclasses.
Общий групповой символ any может обозначать любой класс. Таким образом, вместо описания действий только для класса sun4, можно определить действия для любой архетиктуры, записав:
any:: actions
Если никакого класса не определено, то cfengine устанавливает принятое для классов значение по умолчанию.
Полезный приём при устранении ошибок избегать нежелательных действий, путём изменения их классового имени. Так как cfengine воспринимает любое непонятное имя, как имя хоста, то он просто будет игнорировать неузнаваемые записи. Например:
Myclass:: можно заменить на Xmyclass::
Поскольку Xmyclass уже не соответствует ни одному из созданных классов и не является именем какого-либо хоста, то он будет просто проигнорирован. С этой же целью может также быть использована опция -N (см. приложение к руководству).
Иногда оказывается удобным иметь возможность ограничивать доступ к программе для определённого круга пользователей. Это можно сделать, добавив список доступа в секцию control: программы. Например,
control: ... access = ( mark root )
приведёт к тому, что cfengine откажется запускать программу для любых пользователей за исключением mark и root. Такое ограничение может быть полезно, например, при желании создать скрипт, устанавливающий id пользователя(set-user-id), но так, что только определённые пользователи смогли бы его использовать. Если список доступа отсутствует, то все пользователи могут запускать программу.
Обратите внимание: при запуске cfagent через программу cfrun cfagent всегда начинается с одной и той же пользовательской личности, как и процесс cfservd на удалённом хосте. Как правило, это корневая пользовательская личность (главный пользователь). Это значит, что ключевое слово, по которому осуществляется доступ, никак не повлияет на использование команды cfrun.
В двух действиях - files и tidy задаются имена папок, с которых должны начаться проверка или чистка файлов. Использование групповых символов даёт возможность существенно сэкономить время, позволяя определять целую группу папок, где должны разом запускаться такие же процессы. Например, имена папок
/usr/*/* /bla/*/ab?/bla
представляют все директории (и только директории), которые соответствуют обозначенным строкам групповых символов. Cfagent открывает каждую, удовлетворяющую такому определению папку, и выполняет действие над каждой такой директорией.
Символ ? соответствует любому одиночному символу, тогда как * соответствует любому числу символов, в соответствии с групповыми символами файловой подстановки, определёнными в shell.
Когда такая форма записи используется при задании имён папок, она всегда определяет точку, с которой начинается поиск. Она не выдаёт команд, как искать, а только задаёт место начала. Для задания моделей чистки файлов может быть использована папка pattern в tidy, а под files рассматриваются все файлы (см. приложение к руководству).
Обход файлов представляет собой процесс поиска по всему дереву папок, при котором большое число фалов анализируется и обрабатывается каким-либо образом. Существует много случаев, когда cfagent используется для осуществления обхода файлов:
Проблема при обходе файлов может заключаться в излишней тщательности, так как зачастую нет необходимости анализировать каждый файл из дерева файлов. Возможно желание выполнять поиск
исключая папки с определённым названием и их подпапки с помощью ignore.
исключая файлы и папки, обладающие определёнными свойствами
только на подмножестве файлов, обладающих определённым свойством
не обращая внимания на особые типы фалов
В этом отношении действие tidy немного отличается от прочих, так как уже всегда предполагается, что оно выполняется согласно определённой модели. Как правило, никому не нужно осуществлять обход файлов, удаляя все, не соответствующие заданному образцу: это может оказаться слишком опасным. Именно поэтому синтаксис tidy запрещает использование ignore, include и exclude. Об этом можно прочитать в разделе про удаление файлов (см. приложение к руководству).
Объявления в глобальном разделе ignore затрагивают files, copy, links и tidy. Для обхода файлов внутри files, copy и links можно создать отдельные списки ignore, записав ignore=. Разница между exclude и ignore заключается в том, что последний может работать с абсолютными папками. Он исключает папки, тогда как exclude ищет файлы внутри папок.
Для обхода файлов внутри files и copy можно задавать специальные параметры поиска, используя ключевые слова include= и exclude=, а для версий 1.6.x ещё и filter=. Например,
files: /usr/local/bin m=0755 exclude=*.ps action=fixall
В данном примере cfagent осуществляет поиск по всему файловому дереву (за исключение папок, описанных в списке ignore и фалов, оканчивающихся на .ps), (см. приложение к руководству).
Использование ключевого слова include= немного отличается от остальных, так как оно автоматически сводит поиск только к заданным (через * и ?) образцам, везде и в каких количествах оно бы не встречалось. Если задавать образцы таким способом, то cfagent будет игнорировать любые файлы, которые не соответствуют заданным образцам. Он также будет игнорировать все образцы, которые были определены в глобальном списке игнорирования, как и те, которые были исключены с помощью exclude=pattern. Другими словами, операция exclude всегда аннулирует операцию include.
В случае, если возникает необходимость особым образом обработать исключённый образец или папку, то для них нужно отдельно написать подробную проверку. Например, для того, чтобы обработать исключённые ранее файлы с расширением .ps, потребуется создать нечто подобное:
files: /usr/local/bin m=0644 include=*.ps action=fixall
Важно никогда не заключать групповые символы в кавычки. Кавычки воспринимаются буквально и образец может трактоваться не так, как было задумано.
Для editfiles синтаксис немного отличен. Для редактирования строфы необходимо добавлять строчки:
editfiles: { /tmp/testdir Include .* Exclude bla.* Ignore "." Ignore ".." Recurse 6 ReplaceAll "search" With "replace" }
Рекурсивный обход папок с выполнением масштабных операций деструктивного характера может оказаться весьма опасным, если досконально не знать всей структуры папок.
Предположим, что пользователь, имеющий права доступа к файловой системе, добавил символическую ссылку на /etc/passwd, а затем происходит рекурсивное удаление. Таким образом, cfengine внезапно превращается в инструмент разрушительного действия. Именно поэтому, cfengine по умолчанию не переходит по символическим ссылкам при рекурсивном спуске. Для того, чтобы это поменять, можно установить значение true для параметра travlinks. Однако, как правило, менять значение этого параметра не следует, особенно если ненадёжные пользователи имеют доступ к частям файловой системы, тогда, например, можно рекурсивно удалить /tmp.
Cfagent выявляет атаки путём быстрого создания ссылок, при которых пользователи пытаются заменить папку на ссылку в промежутки между системными вызовами. Таким образом они пытаются обмануть cfagent, заставляя воспринимать ссылку за папку, как в версии 2.0.3.(и 1.6.4.)
Обратите внимание, что даже когда travlinks присвоено значение истины, cfagent не будет следовать по символической ссылке, созданной не владельцем ID пользователя агента. Это сделано для минимизации риска атак быстрыми ссылками, при которых пользователи с правами записи могут перенаправить cfagent в другую часть системы.
Внутри себя cfagent хранит два вида журналов регистрации и позволяет протоколировать его деятельность в системном журнале. Такая функция активизируется с помощью переменной Syslog (см. приложение к руководству).
Первый протокол, хранящийся cfagent, предназначен для каждого пользователя (каждая поддиректория домашней директории файловой системы). Файл ~/.cfengine.rm хранит список всех файлов, удалённых в ходе последнего запуска функции tidy. Это может потребоваться пользователям, чтобы узнать, какие файлы были удалены без их ведома.Также такая функция поможет узнать, что происходит с системой в случае каких-либо сбоев.
Второй файл создаётся, когда cfagent просматривает дерево файлов в ходе действия files. Он представляет собой список всех программ, которые являются setuit root, или setgid root. Так как подобные файлы представляют потенциальную опасность безопасности, то cfagent всегда выдаёт предупреждение, когда встречает новый (т.е. который ещё не находится в списке). Это позволяет системному администратору своевременно отслеживать новые программы, которые появляются и предоставляют пользователям доступ к корню. Журнал регистрации cfagent называется /var/cfengine/cfengine.log. Этот файл не доступен для чтения обычным пользователям.
В нескольких командах cfengine для того, чтобы задать количество текста, который может содержать пробелы, используются строки в кавычках. Например:
control: macro = ( "mycommand" ) editfiles: { $(HOME)/myfile AppendIfNoSuchLine 'This text contains space' }
Для того, чтобы разграничивать строки в каждом из случаев можно использовать любой из трёх видом кавычек или или .
При использовании, например, , такой же символ уже нельзя использовать внутри самой строки. То же самое относится и ко всем остальным типам кавычек. В отличии от shell, cfengine воспринимает все три вида абсолютно одинаково между ними не существует никакой разницы. В версиях до 2.0.7. для того, чтобы процитировать строку, заключённую в кавычки, необходимо использовать тип, отличный от уже используемых. Начиная с версии 2.0.7. знаки кавычек можно опустить.
qstring = ( "One string\"with substring\" escaped" )
Обратите внимание, что для определённых символов в строке можно использовать специальные переменные (см. раздел 3.2. [Замена переменных]).
В cfagent регулярные выражения могут использоваться в сочетании с editfiles и processes для поиска строк, которые удовлетворяют определённым условиям. Регулярное выражение это обобщённый групповой символ. В групповых символах cfagent * и ? могут использоваться для обозначения любого символа или нескольких символов. Работа с регулярными выражениями является более трудной, но зато они гораздо более гибкие в использовании.
Внимание: значение специальных символов * и ?, используемых в групповых символах, отличается от использования их в регулярных выражениях.
Некоторые регулярные выражения соответствуют только единственной строке. Например, каждая строка, не содержащая специальных символов, является регулярным выражением, соответствующим только строке, идентичной ему самому. То есть, регулярное выражение cfengine будет соответствовать только строке cfengine , а не Cfengine или cfengin и т.д. Другие регулярные выражения могут соответствовать и большему количеству срок. Например, регулярное выражение *c будет подходить для любого числа c (включая и одно). Таким образом, это выражение будет соответствовать пустой строке, c, ccc, cccccccc, но не cccx.
Ниже приведён список регулярных вырадений специальных символов и операторов:
\ |
Как правило обратная косая черта имеет определённое предназначение: она либо вводит новую команду, либо выражение, поясняющее, что следующий символ не является специальным. Данный символ означает сам себя, только когда он заключён в квадратные скобки [\] или заключён в кавычки сам с собой \\. |
\b |
Определяет границы слова |
\B |
Ставиться внутри слова (оператора) |
`\<' |
Соответствует началу слова |
`\>' |
Соответствует началу слова |
`\w' | Соответствует символу, который может являться частью слова |
`\W' | Соответствует символу, который не может являться частью слова |
`any character' | Соответствует сам себе |
`.' | Соответствует любому символу |
`*' |
Соответствует любому числу (в частности, нулю) вхождений предшествующего символа. Например, `c*'. Если перед ним не стоит никакого символа, то он представляет звёздочку в буквальном смысле. |
`+' |
Соответствует любому числу (начиная с одного) вхождений следующего за ним символа. |
`?' |
Соответствует нулю или одному вхождению следующего за ним символа. |
`{ }' |
Число вхождений оператора. `{5}' будет соответствовать именно 5 разам вхождения предыдущего символа. `{6,}' будет значить по меньшей мере 6 раз вхождения предыдущего символа. `{7,12}' будет соответствовать от 7 до 12 случаям вхождения последующего символа. Очевидно, что для того, чтобы выражение имело смысл, необходимо, чтобы первое число было меньше второго. |
`|' |
Оператор логического ИЛИ, выполняет операцию логического сложения над двумя регулярными выражениями.. |
`[list]' | Определяет набор символов, которые следует трактовать, как один объект (ORed).Например, `[a-z]'соответствует любому символу от a до z, `abcd' будет соответствовать либо a, либо b, либо c, либо d. Большинство символов внутри списка являются обычными, но существуют исключения: `]' обозначает конец списка, только если не стоит на первом месте, , `\' заключает следующий символ в кавычки, `[:' и `:]' определяют оператор символьного типа (см. ниже), и `-' представляет ряд символов, только если не стоит на первом или последнем месте в списке. |
`[^list]' | определяет список символов, с которыми нельзя осуществлять
сопоставление, то есть строка может совпадать с любыми символами за
исключением находящихся в списке. |
``[:class:]'' | определяет класс символов, используя ctype-library. |
alnum числовой знак начала alpha символ алфавита blank пробел или символ табуляции cntrl управляющий символ digit 0-9 graph print, но без пробелов lower буква нижнего регистра print печатные символы(не управляющие символы) punct символы не являющиеся ни управляющими, ни алфавитными space пробел, символ возврата каретки, символ перевода строки, вертикальная табуляция, символ прогона листа. upper буква верхнего регистра xdigit шестнадцатеричная цифра 0-9, a-f |
|
``( )'' | группирует любое число операторов. |
`\digit' | оператор обратной ссылки (относится к GNU документации regex documentation). |
`^' | Соответствует началу строки |
`$' | Соответствует концу строки |
Ниже приведены несколько примеров. Следует помнить, что некоторые команды ищут регулярные выражения, совпадающие с частью строки, тогда как другим требуется полное совпадение строк (см. приложение к руководству).
^# соответствует строке, начинающейся с символа # ^[^#] соответствует строке, начинающейся не с символа # ^[A-Z].+ соответствует строке, начинающейся с буквы верхнего регистра, следом за которой стоит по меньшей мере один символ.
Переменные списка shell как правило определяются путём объединения списка папок с помощью символа конкатенации, такого как :. Типичным примером может быть переменна PATH:
PATH=/usr/bin:/usr/local/bin:/usr/sbin
Очень удобно иметь возможность использовать такие переменные для того, чтобы заставить cfagent делать итерацию в списках. Это даёт способ компактно записывать повторяющиеся операции и позволяет просто устанавливать взаимодействие со средой shell. В целях безопасности, итерация поддерживается только в следующих ситуациях:
Как правило, это предоставляет возможность взаимодействия в shell с переменными окружения типа PATH.
В приведённых ситуациях, любая переменная которая представляет собой список, объединённый с помощью двоеточия, будет повторяться в течении компиляции. Обратите внимание, что значение разделителя списка можно поменять с помощью переменной Split в секции управления control программы (см. приложение к руководству).
Например, для связи всех бинарных файлов в переменной окружения PATH в единую папку, стирая в ходе этого процесса уже мёртвые ссылки, необходимо написать:
control: actionsequence = ( links tidy ) links: /allbin +> $(PATH) tidy: # Hopefully no-match matches nothing /allbin pattern=no-match age=0 links=tidy
Слово no-match не является зарезервированным в cfengine, это всего лишь строка, которая не должна соответствовать никакому файлу.
Для того, чтобы задать полный список, используя символ пробела в качестве разделителя, необходимо:
control: Split = ( " " ) mylist = ( "mark ricky bad-dude" ) tidy: /mnt/home1/$(mylist) pattern=*.cfsaved age=1
В данном примере действие tidy будет повторяться в директориях `/mnt/home1/mark', `/mnt/home1/ricky' и `/mnt/home1/bad-dude'.
Как правило, число переменных типа списка в любом пути или имени файла должно не превосходить одного или двух, так как случайная комбинация двух списков иногда может создать что-то значащий образец. Единственным очевидным исключением является осуществление итерации в подпапках типа bin, lib и т.д., находящихся в нескольких различных пакетных директориях (package directory).
В данной главе рассказывается о том, как настроить механизмы работы с сетью cfengine для того, чтобы осуществлять удалённое распределение файлов и удалённый запуск cfengine, не подвергая при этом компьютеры возможным атакам, возникающим при использовании rsh протоколов.
Запустив демон, называемый cfservd, можно установить линию связи между компьютерами, что позволит им обмениваться файлами по сети и осуществлять удалённый запуск cfengine с другой системы. Возможности cfengine по работе с сетью реализуются с помощью следующих компонентов:
cfagent | Механизм конфигурации, который взаимодействует с сетью исключительно через удалённые запросы на копирование. Этот компонент выполняет сложную задачу конфигурации системы, основанной на правилах, описанных в файле cfagent.conf. Он не предоставляет и не может предоставить никакого доступа к системе из сети. |
cfservd |
Демон, работающий как в качестве файл-сервера, так и отдалённого исполнителя cfagent. Этот демон проверяет подлинность запросов, поступающих из сети, и обрабатывает их в соответствии с правилами, описанными в cfservd.conf. Он работает и как файл-сервер и как механизм для запуска cfagent на локальном компьютере, а также для передачи результатов его работы обратно сетевому соединению. |
cfrun |
Это простая программа запуска, которая может быть использована для запуска cfagent на нескольких удалённых компьютерах. Её нельзя использовать для сообщения cfagent последовательности действий. Единственное, что она может заставлять cfagent на удалённом компьютере запустить файл конфигурации, который у него уже есть. Данную программу может запускать любой пользователь, поскольку она не требует наличия каких-либо особых прав. Блокирующие механизмы cfengine предотвратят её использование для рассылки спама. |
cfwatch |
Данная программа (не входящая в дистрибутив, поэтому пользователи
должны её устанавливать самостоятельно) создаёт графический интерфейс
пользователя, в котором можно следить за конфигурацией компьютеров, на
которых запущен cfagent, и записывать результаты. |
С помощью данных компонентов можно проделывать ту же работу, что и программы типа rdist, задача которых состоит в проверке и поддержке копий файлов на клиентских компьютерах. Также они позволяют предоставить определённым пользователям права на запуск cfagent и определить возможную частоту запуска, не раздавая при этом никаких пользовательских привилегий.
Данный раздел посвящён настройке cfservd в качестве удалённого файл-сервера, что позволит распространять файлы на компьютеры клиентов более демократичным способом, чем с помощью программ типа rdist.
Важное отличие между cfengine и другими системами заключается в способе распространения файлов. При передаче сетевых файлов cfengine использует схему, при которой, скорее, компьютеры берут, нежели сервер раздаёт. Например, принцип работы команды rdist заключается в том, чтобы заставить все клиентские компьютеры принять копии файлов с одного сервера. При желании сервера файлы могут изменяться, но пользователям ничего не остаётся, как получать результат. Cfagent не может заставить другие компьютеры выполнять его желания таким образом. Он может лишь информировать хосты и предложить им при желании загрузить файлы. Другими словами, cfengine имитирует работу по раздаче файлов, опрашивая каждый компьютер и запуская локальный конфигурационный скрипт, который позволяет загрузить и обновить файлы с удалённого сервера, при чём каждый клиент сам принимает решение о необходимости обновлений.
Кроме того, в отличии от таких программ, как rdist, распространяющих программы на множество компьютеров, cfengine не требует никакого общего корневого доступа к системе с использованием файлов .rhosts или /etc/hosts.equiv. Достаточно просто запустить демон в качестве корня. Однако, его нельзя запустить, добавив в файл /etc/inetd.cof системы. Ограниченные возможности демона защищают систему от попыток выполнять основные команды как привилегированный пользователь, используя rsh.
Для удалённого доступа к фалам на сервере необходимо добавить ключевое слово server=host в команду копирования copy. В следующем примере рассматривается, как можно передать файл с паролем с главного компьютера нескольким клиентским.
copy: PasswdClients:: /etc/passwd dest=/etc/passwd owner=root group=0 server=server-host
Учитывая, что демон cfservd запущен на компьютере-сервере, cfagent установит с ним связь и попытается получить информацию о файле. В течение этого процесса cfengine удостоверится в том, что системные часы на обоих компьютерах достаточно синхронизированы. В противном случае, он не позволит удалённое копирование. Если cfagent установит необходимость обновить файл с удалённого сервера, то он начнёт копировать удалённый файл в новый в той же файловой системе, где должен находиться файл результатов. Этот файл имеет суффикс .cfnew. Только после того, как файл был успешно собран, cfagent скопирует старый файл (см. repository в приложении к руководству) и назовёт новый его именем. Такой принцип используется для того, чтобы избежать состояния гонок (race-conditions), которые могут возникать в ходе сетевых соединений и ,более того, операций, на которые требуется время. Если бы файлы просто копировались на их новые места, то вероятно, что ошибка в сети могла бы прервать передачу, оставляя взамен искажённый файл.
Для того, чтобы избежать зависаний процессов, cfagent делает в сетевых соединениях тайм-ауты на несколько секунд.
Как правило, демон бездействует, ожидания соединений от сети. Такое соединение может возникнуть в результате просьбы получить удалённые файлы, исходящей от программы на другом компьютере, запустившей cfagent. Также соединение может быть установлено программой cfrun, которая просто запрашивает компьютер с работающим демоном локально запустить программу cfengine.
Весьма удобным было бы иметь возможность удалённо управлять cfagent, путём периодического запуска его с помощью cron. Это гарантировало бы, что cfagent будет запущен, даже если администратор не может зайти на компьютер для того, чтобы запустить его самостоятельно. Однако в некоторых ситуациях может потребоваться срочный запуск cfagent с целью внести изменения в конфигурацию как можно скорее. В такой ситуации было бы удобно зайти на каждый компьютер и сделать все действия вручную. Но более удачным решением является создание простой команды, которая связывалась бы с удалённым компьютером и запускала cfagent, выводя результаты работы на экране администратора:
myhost% cfrun remote-host -v output....
Для реализации такой возможности был создан простой пользовательский интерфейс. cfrun устанавливает соединение с удалённым cfservd -демоном и запускает cfagent в системе, которая обладает привилегиями cfservd-демона (обычно это root). В данном процессе есть два преимущества:
Возможный недостаток использования такой системы заключается в том, что злоумышленник имеет возможность запуска cfagent на удалённых компьютерах. Тот факт, что не только пользователи root могут запускать cfagent, не является проблемой самой по себе, поскольку самое плохое, что они могут сделать просмотреть конфигурацию системы и исправить какие-либо возникшие проблемы. С помощью программы cfrun невозможно раздавать cfagent указания, возможно лишь запускать уже созданную конфигурацию. Но большую опасность могут вызвать попытки злоумышленника повторно запускать cfagent (так называемый, спамминг), в следствие чего система становиться загруженной постоянными запусками cfagent. См раздел 6.2.3. [Спамминг и безопасность].
Термин спамминг обозначает бессмысленное повторение чего-либо со злым умыслом вывести кого-либо из себя1. В компьютерной среде некоторым злоумышленникам, немного напоминающим эксгибиционистов в парке2, нравится бродить по сети и самовыражаться, рассылая множество электронных писем или периодически устанавливая сетевые соединения с целью перегрузить систему и людей3.
Каждый раз при подключении системы к сети, эта проблема всплывает заново. Cfagent является инструментом для организации взаимодействия систем, но не орудием, которое можно использовать в периоды бессмысленной агрессии. Однако, демон cfservd позволяет каждому подключаться к сети и запускать процесс cfengine, в связи с чем требуется наличие механизма защиты от подобных атак.
Cfagent решает данную проблему при помощи блокирующих механизмов. Вместо того, чтобы организовывать управление согласно статусам пользователей, он использует блокирующие механизмы, основанные на классах времени. Они позволяют пользователям совершать действия только по истечении определённого минимума с момента последнего момента их выполнения. Использование блокировщика, основанного не на идентификации пользователей, позволяет одновременно удовлетворить несколько целей:
Ограничение доступа cfengine к корню не позволит обычным пользователям решить возникшие проблемы, если администратор по каким-либо причинам недоступен. Блокировщик, основанный на времени, не забирает у пользователей таких возможности.
Неполадки в скриптах cron или shell могут привести к более частому, чем запланировано, запуску cfagent. Необходимо также гарантировать защиту и от таких случаев.
Предотвращать атаки можно вне зависимости от того, кто их осуществляет.
Cfagent контролируется набором блокировщиков, которые не позволяют запускать его слишком часто и тратить слишком много времени, пытаясь выполнить задание. Работа блокировщиков устроена таким образом, что она позволяет осуществлять одновременный запуск нескольких cfengine, избегая столкновений между ними. Исполняющиеся в одно и то же время процессы cfengine также не смогут одновременно выполнять одинаковые действия (это называется спамминг). В последовательности действий action sequence можно осуществлять контроль сразу за двумя аспектами каждого действия:
Данные значения могут быть установлены глобально (для всей системы) и для каждого действия по отдельности. При установке, как глобальных, так и локальных значений, приоритет будет отдаваться локальным. Время всегда задаётся в минутах.
actionsequence ( action.IfElapsedtime-in-mins action.ExpireAftertime-in-mins )
Или глобально
control: IfElapsed = ( time-in-mins ) ExpireAfter = ( time-in-mins )
Например,
control: actionsequence = ( files.IfElapsed240.ExpireAfter180 copy tidy ) IfElapsed = ( 30 )
В данном примере действие files воспринимается не как все остальные. Для всех остальных действий cfagent исполнит файловую часть программы, только если прошло 30 минут с момента её последнего запуска. Поскольку никакого значения не установлено, время истечения для действий составляет 60 минут. Это значит, что любой процесс cfengine, который не успел закончить задание в течение 60 минут, будет автоматически прекращён следующим запускающимся cfagent.
Что касается действия files: оно будет выполняться только по прошествии 240 минут (4 часа) с момента последнего запуска. Аналогично, процесс выполнения files будет прекращён, только по прошествии 180 минут (3 часа).
Данные блокировщики не мешают запуску целого cfagent, а лишь его так называемым атомам. Несколько разных атомов может одновременно запускаться разными cfagent. Допустим, что временные ограничения, установленные выше, позволяют произвести запуск cfengine. Блокировщики гарантируют, что атомы никогда не будут запущены двумя cfagent одновременно, что может привести к конфликту и испортить циклы CPU. Атомы определяются для того, чтобы обеспечивать эффективность и большую безопасность системы. Если бы cfangine блокировал каждый файл, рассматриваемый в отдельности, он бы тратил большое количество времени на работу с блокировщиками, поэтому он этого не делает. Вместо этого он группирует всё вместе, подобно следующему:
copy, editfiles, shellcommands | Каждая отдельная команда имеет своего блокировщика. Это значит, что несколько процессов cfagent может одновременно выполнять несколько таких действий. Множественное или рекурсивное копирование или редактирование воспринимаются как один объект. |
netconfig, resolve, umount, mailcheck, addmounts, disable, processes | Все команды действий данного типа блокируются одновременно, поскольку они могут конфликтовать |
mountall, mountinfo, required, checktimezone | Для данных действий блокировщика не существует. |
Cfagent создаёт директорию `~/.cfengine' для написания блокирующих файлов для обычных пользователей.
Опции -K или --no-lock используются для отмены блокировщиков, но следует обратить внимание, что эти опции недоступны при удалённом запуске cfagent через cfservd.
Для авторизации на компьютерах cfservd использует форму. Каждая маленькая операция, например, статтинг(statting), получение файлов, открытие папок и т.д., требует нового соединения, и каждое соединение проверяется с помощью двустороннего поиска в DNS записях сервера. Одиночные стат структуры(stat structures) кэшируются в ходе обработки файла.
Контрольные суммы MD5 передаются от клиента серверу с целью избежать перегрузки сервера. Даже если бы пользователь мог исказить контрольную сумму MD5, ему или ей пришлось бы пройти контроль доступа последнего IP и самое страшное, что могло бы произойти в таком случае получить правильную версию файла. Всё это придерживается одной идеи, что с помощью cfengine пользователь может навредить только себе, но не другим пользователям.
Каждый раз, как только запущенным процессам разрешается одновременный доступ к одному ресурсу, возникает опасность возникновения конфликта блокировок. Так называется ситуация, когда два или более процессов попадают в возникшее по ошибке тупиковое положение, из которого ни один не может выйти. Другой возможной проблемой является опасность зацикливания: cfagent запускает сам себя.
Cfagent надёжно защищает от возникновения таких циклов. Случайное создание подобного цикла должно быть невозможным. Такую гарантию дают блокирующие механизмы, которые предотвращают возможность частого повторения заданий. Если запустить процесс cfagent, содержащий команду shell, которая снова запускает cfagent, то такая команда будет блокирована, поэтому повторный запуск окажется невозможным. Таким образом, даже если существует возможность начала второго процесса cfagent, то дальнейшие процессы не будут запущены, в результате чего, просто потратится немного времени CPU. По возвращении первого cfagent, задание, которое выполнил второй, будет повторно исполнено исключительно в том случае, если значение IfElapsed или ExpireAfter равно нулю. В целом, во избежание подобных проблем не стоит отключать блокирующие механизмы, установкой нулевых значений.
Вероятность возникновения конфликта блокировок увеличивается в ходе сетевых соединений. Cfengine не станет использовать сеть для копирования файла, который можно скопировать внутренне непосредственно с другого компьютера. Чтобы избежать ненужных сетевых соединений, он всегда будет в копии заменять объявление server= на localhost. Это позволяет иссключить одну из возможных тупиковых ситуации, а именно, cfrun выполняет cfagent на компьютере А (cfservd на компьютере А будет блокирован до окончания этого процесса), но файл конфигурации компьютера А содержит удалённую копию с себя на себя же. Такая удалённая копия будет ждать, пока не разблокируется cfservd, что оказывается невозможным, поскольку cfservd не может быть разблокирован, пока у него есть этот файл. Возможность возникновения такой ситуации устраняется, путём запрещения удалённых копий на localhost.
Для установки демона cfservd, необходимо зарегистрировать порт для cfengine. Для этого в системный файл нужно добавить следующую строчку: `/etc/services file'
cfengine 5308/tcp
Это можно проделать для всех компьютеров, если добавить следующие строки в конфигурацию cfengine
editfiles: { /etc/services AppendIfNoSuchLine "cfengine 5308/tcp" }
Для того, чтобы запустить cfservd во время загрузки, в файлы запуска необходимо добавить строчку подобного вида:
# Start cfengine server cfservd
Обратите внимание, что cfservd будет перечитывать свой файл конфигурации, каждый раз когда он заметит в нём внесённые изменения. Поэтому нет необходимости ни перезапускать демон, ни посылать сигнал HUP, как при работе с другими демонами.
Демон сервера управляется файлом cfservd.conf. Синтаксис данного файла намеренно строился по аналогии с файлом конфигурации cfengine, но несмотря на все сходства, нельзя путать их содержание.
Несмотря на того, что cfagent.conf и cfservd.conf не совместимы, у них есть ряд общих черт:
Обратите внимание, что в классах в файле cfservd.conf не содержится информации о классах компьютеров, имеющих доступ к фалам и папкам. Но в них содержаться данные о классах компьютеров, которые обращают внимание на доступ и отклоняют команды во время анализа файлов.
Идентификация имени компьютера осуществляется не по классу или группе, а по его имени hostname, например, файл /etc/exports в большинстве систем Unix. Синтаксис для такого файла выглядит примерно следующим образом:
_ _ control: classes:: domain = ( DNS-domain-name ) cfrunCommand = ( "script/filename" ) # Quoted MaxConnections = ( maximum number of forked daemons ) IfElapsed = ( time-in-minutes ) DenyBadClocks = ( false ) AllowConnectionsFrom = ( IP numbers ) DenyConnectionsFrom = ( IP numbers ) AllMultipleConnectionsFrom = ( IP numbers ) LogAllConnections = ( false/true ) SkipVerify = ( IP numbers ) groups: Group definitions import: Files to import admit: | grant: classes:: /file-or-directory wildcards/hostnames deny: classes:: /file-or-directory wildcards/hostnames root=hostlist encrypt=true/on
Подробное описания всех элементов можно найти в приложении к руководству. Данный файл состоит из раздела управления control и информации о доступе. В разделе control для удобства можно определять любые переменные, которые планируется использовать в оставшейся части файла.
После раздела control следует список фалов, директорий и компьютеров, которым разрешается доступ к данному файлу. Если права доступа предоставляются определённой директории, то все содержащиеся в ней директории также автоматически получают эти права. Обратите внимание, что символические ссылки на пустые файлы не проверяются, поэтому им требуется отказывать в доступе отдельно. Но cfservd не следует по символьным ссылкам с директорий и не предоставляет доступа к файлам в папках, на которые они указывают.
В данном файле необходимо использовать полностью уточнённые имена компьютеров, в противном случае к ним добавляется текущий домен (не забудьте задать доменное имя). Идентификация вызывает функцию Unix gethostbyname() и так далее для того, чтобы распознать и проверить подключающиеся компьютеры. Поэтому имена в файле должны отражать типы имён, возвращаемые данной функцией. Для того, чтобы задать, например, все компьютеры с определённого домена, при определении имён можно использовать групповые символы. В качестве примера приведём файл:
##################################################### # # This is a cfservd config file # ##################################################### groups: PasswdHost = ( nexus ) ##################################################### control: # # Assuming CFINPUTS is defined # cfrunCommand = ( "/var/cfengine/bin/cfagent" ) variable = ( /usr/local/publicfiles ) ##################################################### admit: # Can also call this grant: # Note that we must grant access to the # agent if we wan to start it remotely with cfrun /var/cfengine/bin/cfagent PasswdHost:: /etc/passwd *.iu.hioslo.no FtpHost:: # An alternative to ftp, grant anyone /local/ftp/pub * # These file paths must not contain symbolic # links. Access control does not follow symlinks. any:: $CFINPUTS/cfrun.sh *.iu.hioslo.no ##################################################### deny: /etc/services borg.iu.hioslo.no /local/ftp *.pain-in-the-ass.com
Внимаение I: cfserved не является rpc.mountd, контроль доспупа происходит по имени файла filename, а не по имени устройства. Не стоит думать, что файлы, лежащие в поддиректориях, не доступны просто потому, что они находятся на другом устройстве. Для того, чтобы избежать символических ссылок, необходимо задавать полный адрес к файлу.
Внимание II: контроль доступа устанавливается для каждого пользователя и каждого компьютера в отдельности. Предполагается, что имена пользователей общие для обоих компьютеров. Подразумевается, что между ними существует полное доверие. Поэтому проверка является ли пользователь на удалённом компьютере тем же, что и пользователь с таким же именем на локальном, не осуществляется.
Внимание III: Cfservd требует предоставлять доступ к файлам, избегая каких-либо символических ссылок. Для того, чтобы получить доступ к файловому объекту, необходимо предоставить доступ к существующему файлу или директории.
Это служит целям безопасности на случай, если группы с доступом по логину к серверу могут предоставить доступ к дополнительным файлам, используя возможность создавать символические ссылки во временной директории, например, /tmp.
Суть компьютерной безопасности защита данных и доступности системы компьютеров. Кратко говоря, ключевыми словами в данном вопросе являются аутентификация, конфиденциальность, честность и доверие. Для того чтобы разобраться в компьютерной безопасности необходимо понять не только взаимоотношения межу компьютерами и возможностями сети, но и пути, по которым к данным компьютерам можно осуществлять доступ. Инструменты, предоставляющие такого рода управление, сложны и, как правило, дорогостоящи.
Безопасность компьютера, в первую очередь, подразумевает *физическую безопасность* - если возможно залезть непосредственно в компьютер, то тогда можно просто развинтить его на части. Но если допустить, что компьютер в физическом смысле в безопасности, то тогда можно начать рассматривать вопросы о безопасности программного обеспечения, которые гораздо сложнее. Главным в безопасности программного обеспечения является контроль доступа и надёжность самого программного обеспечения. Ни один инструмент не может сделать систему безопасной. Все крупные ошибки были сделаны из-за уверенности в том, что один продукт (например, firewall) решит все вопросы безопасности. Например, несколько лет назад взломщик с помощью своего Web-броузера удалил все пользовательские директории с коммутируемого логин-сервера, принадлежащего крупной норвежской телекоммуникационной компании. Это стало возможным даже несмотря на наличие firewall, поскольку web-сервер на взламываемом компьютере был неправильно сконфигурирован. Подводя итог, не существует такого понятия, как безопасная операционная система, firewall или что-либо ещё. В данном вопросе требуется поддерживать постоянную бдительность и приспосабливаемость.
Для многих безопасность воспринимается, как синоним к конфиденциальности сети или проникновениию в сеть. Конфиденциальность это один аспект безопасности, но не сеть является главным врагом. Многие нарушения безопасности происходят изнутри. Между опасностью удалённого доступа из сети и прямого доступа из консоли не существует большой разницы: конфиденциальность тесно связана с контролем доступа, вне зависимости от того, где может находиться потенциальный взломщик. Сосредоточивая всё внимание на заботе о сетевых соединениях, мы забываем о возможной угрозе со стороны внутренних пользователей (например, вахтёр эксперт в компьютерах с доступом к сети или непослушный сын директора, который остался поиграть в мамином офисе, или, совсем невероятное, разозлённый сотрудник, которому кажется, что его труд не ценят). Безопасность программного обеспечения очень обширный вопрос в связи с комплексностью современных компьютерных систем. Он только усложняется возможным соединением с Internet, которое даёт возможность миллионам людей взламывать сетевые системы. Это говорит о том, что безопасность требует жёсткого управления контролем доступа на каждом компьютере отдельно, а не только особенными элементами, такими как firewall.
Эта статья не является простым руководством по безопасности. Скорее, её целью является рассказать, как можно использовать cfengine, чтобы помочь автоматизировать уровень сохранности для всех компьютеров сети. Cfengine инструмент конфигурации сети с двумя аспектами. Это язык для создания экспертной системы. Экспертная система описывает то, как компьютеры и сеть должны выглядеть и работать. Также cfengine является software-роботом, который сравнивает описанную модель с тем, что есть на самом деле, а затем принимается исправлять все отклонения от установок. Во многих случаях он работает как иммунная система, нейтрализуя и восстанавливая повреждённые части. В отличие от пакетов для системного администрирования, содержащих скрипты shell, cfengine является программой на C, что значит его легковесность для ресурсов системы. Кроме того, он работает по принципу конвергенции (сходимости). Это значит, что каждый раз при запуске cfengine система будет всё больше и больше походить на описанную изначально модель, пока, наконец, она не станет абсолютно такой же. Тогда cfengine переходит в состояние покоя, в точности как иммунная система. И как сказал один пользователь: компьютер никогда не становится хуже. Это, естественно, предполагает, что описанная модель и есть желаемый результат. С использованием cfangine построение модели становится синонимичным формулированию и формализации системной политики.
Cfengine является инструментом для обеспечения безопасности именно потому, что политика в отношении безопасности является частью политики системы в целом: одно невозможно без другого. Безопасности не добиться без полного контроля над системой. Cfengine проверяет и даже лечит компьютеры с помощью простых как в управлении, так и понимании действий. С точки зрения автоматизации, управление безопасностью ничем не отличается от обычного каждодневного поддержания системы. Единственное, требуется уделять больше внимания деталям. Нельзя говорить о защите в терминах есть или нет. Она есть всегда, вопрос только в качестве: сильная или слабая; эффективная или неэффективная.
Перед началом необходимо упомянуть об очевидном. Никогда не стоит полагаться на совет касательно конфигурации или безопасности до того, как обдумать его самостоятельно. Примеры, рассмотренные в данном руководстве, всего лишь примеры. Они могут быть использованы без изменений, а, может быть, их потребуется модифицировать. Никогда не следует принимать и использовать пример, не проанализировав его серьёзно и тщательно в первую очередь. Ведь всем понятно, что в любой книге рецептов или советов по достижению успеха даны упрощённые ответы на весьма сложные вопросы, которые и нужно воспринимать таковыми. Другого способа по-настоящему всё понять не существует.
Даже для самой маленькой местной сети желательно создать схему автоматизации процессов конфигурации и поддержки компьютеров, поскольку система имеет свойство достаточно быстро расширяться с одного компьютера до большого количества. Именно поэтому важно разработать масштабируемую модель. Масштабируемость является довольно веской причиной для использования cfengine: один ли компьютер в сети или сотня - не играет никакого значения. Управление cfengine осуществляется из центральной точки, но его действия полностью и равномерно распространяется на всю сеть. Каждый компьютер отвечает за то, чтобы получить копию сетевой модели из надёжного источника, а затем сконфигурировать себя самостоятельно без какого-либо стороннего вмешательства. В отличие от ряда других моделей, cfengine не нужно полагаться на сетевое соединение или удалённые объектные модели.
Кроме того, необходимо интегрирование или возможность управлять взаимодействием компьютеров. Нет ничего хорошего в том, чтобы обладать полным контролем над одним важным компьютером и считать, что это и есть состояние абсолютной безопасности. Если злоумышленник сможет взломать любой компьютер, то, наверняка, он или она сможет добераться и до очень важных, особенно если не следить за всеми. Использование cfengine хороший способ заставить администратора составить политику безопасности \ конфигурирования и затем чётко её придерживаться. Почему cfengine? Существует три причины: а) он навязывает дисциплину на процесс работы, что позволяет сосредоточиться проблемах с должной детальностью, б) он предоставляет масштабируемую автоматизацию процесса управления безопасностью и единый интерфейс для всех компьютеров, в) он без лишних проблем расширяется на любое количество компьютеров. Ниже мы более подробно рассмотрим некоторые из этих вопросов.
Первым шагом в управлении безопасностью является выработка политики безопасности. Это значит чёткое понимание того, что такое безопасность и что необходимо делать в случае, если она будет нарушена. Во многих случаях большую часть политики безопасности можно сформулировать в виде кода cfengine. Он делает её строгой и точной, а также это значит, что робот будет приводить данную политику в действие, не требуя лишней работы со стороны пользователя.
Как и иммунная система, cfengine будет хорошо функционировать даже в условиях частичного соединения, поскольку он заставляет каждый компьютер самостоятельно отвечать за своё состояние. Он не доверяет сетевым соединениям для удалённых вызовов или запросам в стиле COBRA, как, например, Tivoli. Всё что ему требуется подлинная копия документа с конфигурацией системы, хранящемся локально на каждом компьютере. Если она имеется, то ни один из разъединённых компьютеров не останется незащищённым. В худшем случае такой компьютер просто не получит вовремя новую версию системной конфигурации.
Внутри компьютерных систем существует множество отношений, основанных на безоговорочном доверии. И понимать их жизненно необходимо. Если не понимать, кому можно верить, а кому нет, то таким доверием могут легко воспользоваться взломщики, которые более детально продумали этот вопрос.
Например, любой NFS сервер пользовательских домашних директорий доверяет привилегированному пользователю на компьютерах, монтирующих данные директории. Ряд неприятностей предотвращаются за счёт передачи привилегий суперпользователя на нулевого пользователя (user nobody) удалённой системы, но это не является аспектом безопасности, а всего лишь удобство. Привилегированный пользователь всегда может использовать su для того, чтобы стать любым пользователем в его файле с паролем и осуществлять доступ \ изменять любые данные внутри таких файловых систем. Файлы .rlogin и hosts.equiv на машинах Unix предоставляют привилегии главного (или любого другого) пользователя другим компьютерам без аутентификации.
Сбор программного обеспечения с удалённых серверов должен осуществляться с компьютеров, которым гарантированно можно доверять, особенно если это файлы, которые могут предоставить особые привилегии доступа к системе. Даже контрольные суммы не окажутся эффективными, если им нельзя доверять. Например, невероятно глупым было бы копировать бинарную программу, как, например, /bin/ps с компьютера, о котором ничего неизвестно. Эта программа запускается с привилегиями главного (root) пользователя. Если кто-нибудь заменил бы эту версию ps Троянским конём, то безопасность системы встала бы под угрозу. Многие пользователи доверяют анонимным FTP серверам, с которых они бесплатно скачивают программное обеспечение. В ходе любого удалённого копирования устанавливаются полностью доверительные отношения. В первую очередь, это вера в честность компьютера, с которого закачиваются файлы. Во-вторых, если говорить о контроле доступа, это вера в то, что они имеют такую же базу данных с именами пользователей. Привилегированный пользователь на скачивающем компьютере имеет такие же права на чтение файлов, что и привилегированный пользователь на сервере. Это же относится и к любому совпадающему имени пользователя.
Cfengine имеет очень простую модель доверия. Он полагается на целостность своего входного файла и надёжность любых данных, которые выбраны для загрузки. Cfengine возлагает ответственность только на корень localhost и не на какие внешние. Только пользователь, и никто другой, может заставить cfengine разрушить систему, также как может разрушить её и самостоятельно. По крайней мере, до тех пор, пока он внимательно следит за входным файлом, который ни в коем случае нельзя никому доверять. Это будет рассмотрено подробнее для случая удалённого копирования файлов.
Cfengine предполагает, что его входной файл полностью надёжен. За исключением этого входного файла, ни одна часть cfengine не принимает и не использует никакой информации о конфигурации от внешних источников. Максимум, что можно сделать через достоверное сетевое соединение попросить cfengine выполнить (или не выполнять) определённые части его модели. Таким образом, в худшем случае взломщик может заставить программу правильно сконфигурировать его компьютер. Говоря коротко, никто за исключением корня localhost может заставить программу выполнять какие-либо действия (если только доступ к корню системы уже не был взломан каким-то другим путём). Это значит, что существует только одна возможность взлома. Входной файл даже не должен быть приватным, поскольку он является аутентичным. Никто, кроме главного пользователя, не может управлять работой cfengine.
Однако существует один подвох. Cfengine может быть использован для удалённой пересылки файлов. В ходе удалённой передачи также необходимо доверять надёжности получаемых данных, как и в случае удалённого копирования. Несмотря на то, что cfengine усиленно пытается установить подлинность компьютера, как только однажды она была установлена, он уже не сможет проверять точность неизвестных получаемых данных. Кроме того, как и в случае со всеми удалёнными передачами файлов, cfengine может быть обманут DNS "спуфингом" при соединении с платным хостом. Поэтому, если Вы не доверяете своему DNS сервису, используйте IP адреса, а не имена компьютеров. Коротко говоря, такие проблемы часто возникают при удалённом копировании и никак не связаны с работой cfengine. Кроме того, это никак не связано с шифрованием, как иногда думают пользователи: шифрование соединения не влияет вышеупомянутые доверительные отношения, они улучшают систему защиты передаваемых данных, но никак не их точность или достоверность.
Особенность cfengine наличие, как правило, одной для всех компьютеров глобальной конфигурации, которую необходимо каким-либо образом распространить. Это значит, что компьютеры должны скачать этот файл с удалённого сервера, что, в свою очередь, означает необходимость доверять компьютерам, обладающим мастерской копией файла конфигурации cfengine.
Безопасность начинается с правильной конфигурации компьютеров. Даже при наличии firewall, защищающего от внешних вторжений, неправильная конфигурация это потенциальная опасность для безопасности. Главная задача cfengine состоит в конфигурации компьютеров, поэтому по этой теме мы легко смогли написать книгу. Нежели, чем снова повторять весь обширный материал, лучше перейти к рассмотрению нескольких примеров, которые решают поставленные задачи и смогут применяться на деле без каких-либо дальнейших доработок.
Файл конфигурации cfengine состоит из объектов со следующим синтаксисом (см. документацию к cfengine):
rule-type: classes-of-host-this-applies-to:: Actual rule 1 Actual rule 2 ...
В rule-type входить проверка полномочий на работу с файлом, редактирование текстовых файлов, блокирование (переименование и удаление прав доступа) файлов, контролируемое выполнение скриптов и множество других функций, связанных с конфигурацией компьютеров. Некоторые из правил управления являются простыми флажками, которые включают сложные (равно полезные) действия. В каждой программе cfengine должна присутствовать последовательность действий actionsequence, которая устанавливает порядок, в котором должны выполняться операции по конфигурации. Например:
control: actionsequence = ( netconfig copy processes editfiles )
Для того чтобы начать создание собственной конфигурации, необходимо обратиться к руководству cfengine.
Давайте пропустим ряд основных положений, которые могут повторяться в различных контекстах.
В качестве показательных примеров будет использована Solaris, а операционными системами в примерах будут GNU/Linux. Они выбраны не для того, чтобы выделить их как наиболее или наименее надёжные, а исключительно из соображений их распространённости и определённости.
Одним из самых простых заданий, которые постоянно приходится выполнять, является блокировка опасных программ при обнаружении ошибок. Предупреждения от CERT часто информируют о наличии программ с ошибками, которые могут поставить под угрозу безопасность системы. В cfengine блокировка файла означает переименование в *.cfdisabled, и присваивание правам доступа значения 600.
disable: # # CERT security patches # solaris:: /usr/openwin/bin/kcms_calibrate /usr/openwin/bin/kcms_configure /usr/bin/admintool /etc/rc2.d/S99dtlogin /usr/lib/expreserve linux:: /sbin/dip-3.3.7n /etc/sudoers /usr/bin/sudoers
Несмотря на то, что это довольно тривиальная задача, но факт её автоматизации означает, что cfengine будет осуществлять такую проверку постоянно. До тех пор пока компьютер включён и работает (вне зависимости, подключён он к сети или нет) cfengine будет гарантировать отсутствие названного файла.
Другая задача состоит в замене стандартных программ поставщика на различные обновления. Например, большинство администраторов хотело бы заменить sednmail поставщика на последнюю версию с сайта Эрика Альмана (Eric Allman). Один из способов сделать это скачать новый sendmail в специальную папку, отделить от файлов поставщика, а затем создать символическую ссылку на новою программу.
links: solaris||linux:: /usr/lib/sendmail ->! /usr/local/lib/mail/bin/sendmail-8.9.3 /usr/sbin/sendmail ->! /usr/local/lib/mail/bin/sendmail-8.9.3 /etc/mail/sendmail.cf ->! /usr/local/lib/mail/etc/sendmail.cf
Восклицательные знаки (по аналогии с csh) означают, что существующие файловые объекты должны быть заменены ссылками на названные файлы. Повторим, что целостность данных ссылок проверяется каждый раз при запуске cfengine. Если объект /usr/lib/sendmail не является ссылкой на названный файл, то старый файл будет удалён и создана соответствующая ссылка. Если ссылка нужная ссылка уже существует, то ничего не произойдёт. После установки нового sendmail необходимо убедиться, что ограниченная конфигурация shell находится в полном порядке.
# # Sendmail, restricted shell needs these links # solaris:: # Most of these will only be run on the MailHost # but flist (procmail) is run during sending... /usr/adm/sm.bin/vacation -> /usr/ucb/vacation /usr/adm/sm.bin/flist -> /home/listmgr/.bin/flist linux:: /usr/adm/sm.bin/vacation -> /usr/bin/vacation
Управление ссылками необычайно полезный инструмент cfengine. Включив ссылки links (по факту, все системные модификации) в конфигурацию cfengine и уже никогда не делая ничего руками, можно создать систему, легко поддающуюся к переустановке. При потере компьютера, необходимо всего лишь один или два раза запустить cfengine, чтобы восстановить его.
Безусловно, главным принципом обеспечения безопасности является возможность ограничения доступа к ресурсам. В связи с этим необходимо проверять права доступа к файлам. Например, последнее сообщение от CERT предупредило о возникших проблемах с некоторыми бесплатными командами монтирования unix, которые были setuid суперпользователя. Если предположить существование группы компьютеров под названием securehosts, с которыми точно всё в порядке, тогда необходимо переместить кусочки setuid (setuid bits) на все компьютеры, как в данном примере:
files: !securehosts.linux:: /bin/mount mode=555 owner=root action=fixall /bin/umount mode=555 owner=root action=fixall securehosts.linux:: /bin/mount m=6555 o=root action=fixall /bin/umount m=6555 o=root action=fixall
Cfengine превосходит многие другие инструменты в своих возможностях по редактированию файлов ascii. Редактирование текстовых файлов без нарушения информации является настолько важной операцией, что использовав однажды, уже невозможно представить, как можно было обходиться без неё. Ниже приведены простые, но вполне реальные примеры того, как можно использовать редактирование файлов:
editfiles: # sun4, who are they kidding? { /etc/hosts.equiv HashCommentLinesContaining "+" } # # CERT security patch for vold vulnerability # sunos_5_4:: { /etc/rmmount.conf HashCommentLinesContaining "action cdrom" HashCommentLinesContaining "action floppy" }
Конфигурацией упаковщика TCP можно легко управлять, поддерживая пару master файлов на надёжных компьютерах. Файлы типа
# /etc/hosts.allow (exceptions) # # Public services sendmail: ALL in.ftpd: ALL sshd: ALL # Private services in.fingerd: .example.org LOCAL in.cfingerd: .example.org LOCAL sshdfwd-X11: .example.org LOCAL # Portmapper has to use IP series portmap: 128.39.89. 128.39.74. 128.39.75.
и
# /etc/hosts.deny (default) ALL: ALL
могут быть переданы cfengine на каждый компьютер
copy: /masterfiles/hosts.deny dest=/etc/hosts.deny mode=644 server=trusted /masterfiles/hosts.allow dest=/etc/hosts.allow mode=644 server=trusted
и устанавливать их следующим способом
editfiles: { /etc/inet/inetd.conf # Make sure we're using tcp wrappers ReplaceAll "/usr/sbin/in.ftpd" With "/local/sbin/tcpd" ReplaceAll "/usr/sbin/in.telnetd" With "/local/sbin/tcpd" ReplaceAll "/usr/sbin/in.rshd" With "/local/sbin/tcpd" ReplaceAll "/usr/sbin/in.rlogind" With "/local/sbin/tcpd" processes: "inetd" signal=hup
Сервисы, в которых нет необходимости, будут удалены все сразу. Нет смысла испытывать судьбу:
editfiles: { /etc/inetd.conf # Eliminate unwanted services HashCommentLinesContaining "rwall" HashCommentLinesContaining "/usr/sbin/in.fingerd" HashCommentLinesContaining "comsat" HashCommentLinesContaining "exec" HashCommentLinesContaining "talk" HashCommentLinesContaining "echo" HashCommentLinesContaining "discard" HashCommentLinesContaining "charge" HashCommentLinesContaining "quotas" HashCommentLinesContaining "users" HashCommentLinesContaining "spray" HashCommentLinesContaining "sadmin" HashCommentLinesContaining "rstat" HashCommentLinesContaining "kcms" HashCommentLinesContaining "comsat" HashCommentLinesContaining "xaudio" HashCommentLinesContaining "uucp" }
В управлении процессами нас, как правило, интересуют три вещи: 1) гарантировать выполнение определённых процессов, 2) гарантировать НЕвыполнение определённых процессов и 3) отправить HUP сигналы для обновления конфигурации. Для того чтобы прервать работу демона (HUP a daemon) и убедиться, что он работает, необходимо написать:
processes: linux:: "inetd" signal=hup restart "/usr/sbin/inetd" useshell=false "xntp" restart "/local/sbin/xntpd" useshell=false
Опция useshell говорит cfengine не использовать shell для запуска программы. Это делается для того, чтобы обеспечить защиту от IFS атак. К сожалению, некоторым программам для запуска необходимо shell, но таких меньшинство. Это является дополнительной мерой предосторожности. При отказе работы демона cron его перезапуск может быть весьма проблематичным, поскольку он не закрывает должным образом свои заполненные дескрипторы (filed descriptors) вовремя разветвлений. В таком случае помогает использование опции dumb:
"cron" matches=>1 restart "/etc/init.d/cron start" useshell=dumb
Для уничтоженного процесса, который не нужно запускать, пишем:
processes: solaris:: # # Don't want CDE stuff or SNMP peepholes... # "ttdbserverd" signal=kill "snmpd" signal=kill "mibiisa" signal=kill
Несколько лет назад полностью сломанный аккаунт был обнаружен в колледже Осло с помощью следующего теста в конфигурации cfengine:
processes: # Ping attack ? "ping" signal=kill inform=true
Существует несколько разумных причин использовать команду ping более чем пару раз. Вероятность того, что cfengine заметит отдельные команды ping, достаточно мала. Но совсем по-другому ситуация обстоит со слаженными ping-атаками. Когда было обнаружено, что на одном из пользовательских компьютеров двадцать ping-процессов пыталось послать большие ping-пакеты компьютерам в США, было очевидно, что данный аккаунт был взломан. К счастью для получателя, программа отправителя пакетов (ping) была написана неправильно и, скорее всего, её никто бы и не заметил.
processes: "sshd" restart "/local/sbin/sshd" useshell=false "snmp" signal=kill "mibiisa" signal=kill "named" matches=>1 restart "/local/bind/bin/named" useshell=false # Do the network community a service and run this "identd" restart "/local/sbin/identd" inform=true
Управление процессами также включает в себя множество других операции, которые мы кратко рассмотрим позже.
Практически все существующие программы безопасности созданы для того, чтобы отслеживать целостность файлов. Cfengine также имеет несколько инструментов для осуществления этого процесса. Ниже приведены некоторые элементы достаточно сложной файловой команды:
files: classes:: /file-object mode=mode owner=uid-list group=gid-list action=fixall/warnall.. ignore=pattern include=pattern exclude=pattern checksum=md5 syslog=true/on/false/off
Кроме того, существуют дополнительные флаги для файловых систем BSD, а также способы управления файлами ACL для таких файловых систем, как NT. Ниже приведены несколько примеров основных проверок прав доступа к файлам.
classes: # Define a class of hosts based on a test... have_shadow = ( `/bin/test -f /etc/shadow` ) NFSservers = ( server1 server2 ) files: any:: /etc/passwd mode=0644 o=root g=other action=fixplain have_shadow:: /etc/shadow mode=0400 o=root g=other action=fixplain # Takes a while so do this at midnight and only on servers NFSservers.Hr00:: /usr/local mode=-0002 Check no files are writable! recurse=inf owner=root,bin group=0,1,2,3,4,5,6,7,staff action=fixall
В последнем примере анализируется вся файловая система (recurse=inf), в результате чего совсем без проблем организуется несколько проверок. Будет сообщено не только о любых подозрительных именах файлов, но и о любой к тому моменту неизвестной программе setuid.
Cfengine всегда с особой осторожностью относиться к файлам, которые являются setuid или setgid суперпользователями (setuid setgid root). Он не станет активно осуществлять их поиск без специального запроса, но каждый раз при запуске cfagent для проверки файла или директории со свойствами файлов он обязательно отметит найденные программы setuid. Это будет записано в файле cfengine.host.log, находящийся в /var/cfengine или /var/log/cfengine. Каждый раз при обнаружении программ setuid, будет выдано предупреждение, но только суперпользователю. Для того чтобы иметь полный список, необходимо очистить журнал регистрации, тогда cfengine будет считать все найденные программы setuid новыми. Журнал регистрации не доступен для чтения обычным пользователям.
Каждый раз, когда cfagent открывает папку и просматривает файлы и директории (рекурсивно) (file, tidy, copy), он также отслеживает наличие подозрительных файловых имён, то есть файлов типа ..., содержащих пробелы и \ или точки. Такие файлы редко создаются в разумных целях, но часто используются взломщиками для маскировнки опасных программ. Cfagent выдаёт предупреждения о наличии таких фалов. Хотя это не обязательно связано с вопросами безопасности, но при желании cfagent также может предупреждать о файловых именах, содержащих непечатаемые символы и о папках, которые стали выглядеть как пустые файлы из-за присваивания им файловых расширений.
control: # # Security checks # NonAlphaNumFiles = ( on ) FileExtensions = ( o a c gif jpg html ) # etc SuspiciousNames = ( .mo lrk3 lkr3 )
Список файловых расширений может быть использован, для того чтобы обнаружить скрытые директории в ходе таких поисков. Если пользователи создают директории, которые выглядят как обычные файлы, об этом обязательно будет сообщено. Дополнительная проверка подозрительных имён файлов, естественно, может осуществляться автоматически, о чём будет рассказано ниже.
Для того чтобы спрятать скаченные файлы, пользователи часто используют папку почтового спулера. Следующие опции информируют о файлах, которые не несут имя пользователя или их владельцами являются недействительные пользователи:
control: WarnNonOwnerMail = ( true ) WarnNonUserMail = ( true ) # Warn about mail which is not owned by a user
Соответствующие команды существуют и для быстрого удаления таких файлов. Они могут быть эффективно использованы для того, чтобы почистить систему после пользователей, чьи аккаунты были удалены.
Cfagent может быть использован для того, чтобы проверять наличие изменений в файлах, которые может определить только такой точный инструмент, как MD5 контрольная сумма \ дайджест. Если определить базу данных контрольных сумм и активировать их проверку,
control: ChecksumUpdates = ( false ) files: /filename checksum=md5 .... /dirname checksum=md5 recurse=inf.... # If the database isn't secure, nothing is secure... /var/cfengine/cache.db mode=600 owner=root action=fixall
то cfagent создаст базу данных с контрольными суммами всех файлов и будет выдавать соответствующие сообщения при их изменении. Это позволяет cfagent работать как Tripware (на данный момент только с контрольными суммами MD5). Он может быть использован для обнаружения троянских версий программ. Однако не стоит прибегать к этой функции часто, поскольку управление базами данных и вычисление контрольных сумм требуют больших ресурсов и могут значительно увеличить время работы cfagent. Переменной ChecksumUpdates (обычно её значение ложь) может быть присвоено значение истины, чтобы обновлять базы данных контрольных сумм при внесении по разумным причинам изменений в программу.
Конечно, нет ничего плохого в выдаче предупреждений, но cfengine был создан не для того, чтобы постоянно беспокоить ими пользователя, а для того, чтобы автоматически исправлять ошибки. Предупреждения являются полезным дополнением, но при возникновении проблем с безопасностью лучше решать их, а не оставлять в компьютер в опасном состоянии. Для того чтобы заботиться о целостности системы, необходимо не только решать вопросы несовпадения контрольных сумм, но и вместо простого чтения делать сравнение копий md5, содержащих правильные и надёжные версии файла. В таком случае при возникновении проблем с двоичным кодом, возможно будет не только узнать об этом, но и мгновенно исправить все повреждения.
Для того чтобы cfagent обновлял базы данных контрольных сумм каждый раз при обнаружении изменений, можно включить переменную управления ChecksumUpdates.
Приведённый ниже список может быть использован для задания расширений, которые система быдет воспринимать как пустые файлы. В рамках общей проверки безопасности cfagent будет предупреждать обо всех папках, в названиях которых использованы перечисленные расширения. Также они могут быть использованы для маскировки директорий.
FileExtensions = ( c o gif jpg html )
Если включить данную опцию, то cfagent будет распознавать и блокировать файлы, имена которых не являются буквенно-цифровыми, то есть которые могли быть случайно или специально замаскированы. Такие файлы помечаются суффиксом .cf-nonalpha и считаются видимыми.
NonAlphaNumFiles = ( on )
Эти файлы можно почистить (удалить) или блокировать, осуществляя поиск на соответствие с образцом. Обратите внимание, что буквенно-цифровой обозначает из кода ascii менее 32 и более 126.
Можно беспокоится о том, что взломщики выведут из строя системы и сделают её полностью непригодной для пользования, тогда как довольно много операционных систем спрограммированы так, что могут сделать это самостоятельно. Существует довольно мало систем, которые могут справиться с переполненным системным диском, и, по факту, большинство журналов регистрации продолжают заполнять диск, никогда не проверяя, есть ли на нём ещё место. Коротко говоря, они губят сами себя мнимыми DoS атаками. Cfagent может справиться с такой проблемой с помощью частого обновления журнала регистрации и очистки папок с временными файлами.
disable: Tuesday.Hr00:: # # Disabling these log files weekly prevents them from # growing so enormous that they fill the disk! # /local/iu/httpd/logs/access_log rotate=2 /local/iu/httpd/logs/agent_log rotate=2 /local/iu/httpd/logs/error_log rotate=2 /local/iu/httpd/logs/referer_log rotate=2 FTPserver.Sunday:: /local/iu/logs/xferlog rotate=3 tidy: /tmp pattern=* age=1
Процедура сбора ненужного материала является необычайно важной. Существует множество причин, по которым таблицы процессов заполняются незавершёнными процессами. Одной из них может стать неисправное программное обеспечение X-terminal, которое не удаляет свои дочерние записи при выходе. Другой пример: такие программы, как netscape и pine, часто зацикливаются, постепенно загружая систему растущим количеством устарелых данных. Простое удаление старых процессов может возродить систему к жизни, не оставляя при этом ничего ненужного. Если компьютер выполняет важные обязанности, то такие упущения могут нарушить работу ключевых функций. Это также предоставляет пользователям возможность отражать DoS атаки на систему.
Если пользователи всегда выходят из системы в конце для и входят на следующий, то с этим легко может справиться cfagent. Ниже приведён код для того, чтобы убивать постоянно повторяемые процессы. Обратите внимание, что на системах типа BSD опции aux требуют наличия соответствующих процессов:
processes: linux|freebsd|sun4:: SetOptionString "aux" any:: "Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec" signal=kill include=ftpd include=tcsh include=xterm include=netscape include=ftp include=pine include=perl include=irc include=java include=/bin/ls include=emacs include=passwd
Данный пример работает следующим образом: через один день после существования процессов название месяца появляется в дате их запуска. Этому соответствует регулярное выражение. Затем операции include фильтруют список процессов, выбирая те, которые содержат указанные строки. В некоторых системах типа BSD строкой ps по умолчанию является -ax, поэтому, для того чтобы всё это заработало, может потребоваться заменить её чем-то, что добавит дату начала.
Другой задачей в управлении процессами является удаление зависнувших, вышедших из-под контроля или оставшихся от старых входов в систему процессов. Ниже приводится регулярное выражение, которое определяет процессы, относящиеся не к суперпользователю и работающие более 100 часов времени CPU. К сожалению, ситуация, когда программа попадает в бесконечный цикл, является весьма распространённой, и она может оставить другие процессы без ресурсов в ходе весьма эффективной DoS атаки.
any:: # # Kill processes which have run on for too long e.g. 999:99 cpu time # Careful a pattern to match 99:99 will kill everything! # "[0-9][0-9][0-9][0-9]:[0-9][0-9]" signal=term exclude=root "[0-9][0-9][0-9]:[0-9][0-9]" signal=term exclude=root
При работе в NT всё это не так просто, поскольку таблица процессов для библиотеки cegwin создаётся только для процессов, которые были запущены программами, работающими под эмуляцией процессов Unix. (working under Unix process emulation). Надеемся, что этот недостаток вскоре будет исправлен.
При конфигурации таких сервисов, как анонимные FTP необходимо сохранять определённую бдительность. Было бы хорошо автоматизировать этот процесс и позволить cfengine следить за правильностью выполнения процесса. Обратите внимание, всегда необходимо убеждаться в надёжности программы ls, используемой анонимным FTP сервером. Для этого она сравнивается с сигнатурой md5 надёжной версии программы. Если по каким-либо причинам она была заменена троянским конём, cfagent заметит несовпадение в контрольной сумме (md5), перенесёт плохую программу на ls.cf-saved и незамедлительно заменит её правильной версией, не дожидаясь действий администратора. Опции inform и syslog отвечают за вывод подробного предупреждения о выполняемом копировании. Ниже приведена полная программа для установки и поддержания анонимного FTP для компьютеров Solaris.
control: actionsequence = ( directories copy editfiles files ) # Define variables ftp = ( /usr/local/ftp ) uid = ( 99 ) # ftp user gid = ( 99 ) # ftp group directories: solaris:: $(ftp)/pub mode=644 owner=root group=other $(ftp)/etc mode=111 owner=root group=other $(ftp)/dev mode=555 owner=root group=other $(ftp)/usr mode=555 owner=root group=other $(ftp)/usr/lib mode=555 owner=root group=other files: solaris:: $(ftp)/etc/passwd mode=644 o=root action=fixplain $(ftp)/etc/shadow mode=400 o=root action=fixplain $(ftp)/pub mode=644 owner=ftp action=fixall recurse=inf copy: solaris:: # Make sure ls is a trusted program by copying # a secure location... /bin/ls dest=$(ftp)/usr/bin/ls mode=111 owner=root type=checksum inform=true syslog=true /etc/netconfig dest=$(ftp)/etc/netconfig mode=444 o=root /devices/pseudo/mm@0:zero dest=$(ftp)/dev/zero mode=666 o=root /devices/pseudo/clone@0:tcp dest=$(ftp)/dev/tcp mode=444 o=root /devices/pseudo/clone@0:udp dest=$(ftp)/dev/udp mode=666 o=root /devices/pseudo/tl@0:ticotsord dest=$(ftp)/dev/ticotsord mode=666 o=root /usr/lib dest=$(ftp)/usr/lib recurse=2 mode=444 owner=root backup=false include=ld.so* include=libc.so* include=libdl.so* include=libmp.so* include=libnsl.so* include=libsocket.so* include=nss_compat.so* include=nss_dns.so* include=nss_files.so* include=nss_nis.so* include=nss_nisplus.so* include=nss_xfn.so* include=straddr.so* /usr/share/lib/zoneinfo dest=$(ftp)/usr/share/lib/zoneinfo mode=444 recurse=2 o=root type=binary editfiles: solaris:: # # Make sure that umask is right for ftpd # or files can be left 666 after upload! # { /etc/rc2.d/S72inetsvc PrependIfNoSuchLine "umask 022" } { $(ftp)/etc/passwd AutoCreate EmptyEntireFilePlease AppendIfNoSuchLine "ftp:x:$(uid):$(gid):Anonymous FTP:$(ftp):/bin/sync" } { $(ftp)/etc/group AutoCreate EmptyEntireFilePlease AppendIfNoSuchLine "ftp::$(gid):" } { $(ftp)/etc/shadow AutoCreate EmptyEntireFilePlease AppendIfNoSuchLine "ftp:NP:6445::::::" } # Finally...useful for chown { /etc/passwd AppendIfNoSuchLine "ftp:x:$(uid):$(gid):Anonymous FTP:$(ftp):/bin/sync" } { /etc/group AppendIfNoSuchLine "ftp::$(gid):" }
Безопасность вэб вряд ли является чем-то парадоксальным. С одной стороны, система создаётся для распространения файлов кому угодно без запроса пароля. С другой стороны, хотелось бы установить некоторые ограничения на то, кто и какую информацию может получать, и кто и какой может обмениваться. При желании обеспечить конфиденциальность в вэб необходимо исключить возможность запуска CGI скриптов, которым нельзя доверять (т.е. CGI программ, которые были написаны кем-то другим), поскольку данные программы могут подорвать безопасность любого сервера. Это вызвано особенной ненадёжностью работы WWW серверов. Написанные пользователями CGI скрипты просто несовместимы с понятием безопасных WWW зон.
Главная проблема CGI состоит в следующем: для того, чтобы демон httpd смог прочитать информацию для публикации, эта информация должна быть читабельной для UID, с которым работает httpd. Например, особенный пользователь www (никого не стоит запускать с uid, поскольку это может быть перепутано с отображениями NFS)). Но программы CGI также автоматически запускаются с www UID. Поскольку нельзя ограничить действия CGI программ, написанных кем-то другим, то любая CGI программа автоматически получает обычные права доступа к любому файлу, видимому серверу. CGI программа может отрыть любой ограниченный в доступе файл, подрывая тем самым безопасность демона. Говоря кратко, конфиденциальность требует отдельного UID (отдельного демона и номер порта) или же отдельного серверного компьютера.
С учётом такого недостатка, cfengine по-прежнему может использоваться для управления разрешениями и правами доступа к файлам на, скажем, двух WWW серверах с центрального компьютера. Представим ситуацию, когда существует общий WWW сервер и конфиденциальный WWW сервер и предположим, что у них есть общая пользовательская / UID база данных. Начнём с определения пользовательского ID и ID группы для общих и частных сервисов. Такие ID должны быть разными для того, чтобы предотвратить описанную выше опасность.
editfiles: wwwpublic:: { $(publicdocroot)/.htaccess AutoCreate EmptyEntireFilePlease AppendLine "order deny,allow" AppendLine "deny from all" AppendLine "allow from all" } wwwprivate:: { $(privatedocroot)/.htaccess AutoCreate EmptyEntireFilePlease AppendLine "order deny,allow" AppendLine "deny from all" AppendLine "allow .example.org" }
Документы должны принадлежать пользователю и группе, которые не совпадают с UID / GID, с которыми работает демон. В противном случае, программы CGI и различные доработки на сервере могут записать или удалить эти файлы. Также необходимо убедиться, что данные файлы доступны для чтения www демону, для того чтобы можно было использовать команду files. Возможно, потребуется предоставить группе людей доступ в этим фалам с возможностью редактировать их содержимое.
files: wwwprivate:: $(privatedocroot) mode=664 owner=priv-data group=priv-data act=fixall wwwpublic:: $(publicdocroot) mode=664 owner=public-data group=public-data act=fixall
control: SecureInput = ( on )
При вставке данных строк cfengine не будет читать файлы, которые принадлежат не uid, запускающему программу, или которые доступны для записи группам и другим лицам.
Шифрование (конфиденциальность) не часто оказываться серьёзной задачей системного администрирования. За исключением раздачи паролей и секретных ключей, не существует причины поддерживать какой-либо уровень конфиденциальности при передаче системных файлов (бинарных, например). Использовать инструмент типа cfengine для передачи секретов компании с одного компьютера на другой было бы просто безумством. Cfengine не предназначен для сверх безопасной передачи данных, но он может быть использован для простого распространения файлов по зашифрованным каналам (например, вместо NIS или другого инструмента передачи паролей). Cfengine использует трёхвариантную DES реализацию в дистрибуции OpenSSL (или эквивалентов) с целью обеспечить достаточно высокую степень конфиденциальности при удалённом копировании.
Аутентификация является самой важной частью системной безопасности. Безопасности невозможно добиться без возможности гарантировать подлинность пользователя или надёжность информации. Несмотря на то, что такие сервисы, как pidentd могут выполнять некоторые операции по проверке подлинности пользователя, но единственным поистине надёжным способом это сделать является использование общего секрета, т.е. пароля. Принцип работы пароля заключается в том, что две стороны, которые хотят доверять друг другу, должны знать какую-либо информацию, неизвестную стороне, которой не доверяют.
В скорее после второй мировой войны ныне известная пара Джулиус и Эсель Розенберг (Julius, Ethel Rosenberg) были осуждены и приговорены к смертной казни за шпионаж за проектом американской бомбы для Советского Союза в 1953. Однажды они придумали довольно умную систему паролей: картонная коробка из-под мусса была разорвана на две части, одна из которых отдавалась агенту, которого им затем нужно было идентифицировать. Сложная форма оборванных краёв и совпадение рисунка создали ключ, который было практически невозможно подделать. Наши тела используют такую же систему рецепторной идентификации молекул как для обоняния (с некоторыми особенностями), так и для иммунных реакций. Без сопоставления секретной информации невозможно установить подлинность чьей-либо личности.
Для того чтобы скопировать файл по зашифрованному каналу, необходимо написать:
copy: source dest=destination encrypt=true server=myserver trustkey=true
Необходимо всегда помнить, что сервер должен представлять собой компьютер, которому доверяют. Конфиденциальность не поможет, если собираемые данные окажутся повреждёнными. Для того чтобы использовать шифрование, на каждом компьютере должна существовать пара открытых / частных ключей. Открытый ключ должен быть известен обоим компьютерам. Для генерации нового файла с ключом можно использовать программу cfkey. Затем этот открытый ключ должен быть передан. Cfagent / cfrun и cfservd могут осуществлять безопасное распространение ключей по сети. На данном этапе не должно возникнуть никаких проблем, если Вы доверяете источникам данных ключей (как узнать, что ключ поступил именно от того компьютера / пользователя, от которого это заявлено?).
Через зашифрованные соединения cfengine скрывает имена и содержимое файлов. Если файлы с частным ключом являются конфиденциальными, то это влечет за собой дополнительные действия в виде аутентификации обоих компьютеров друг для друга.
Сервер может решать, должен ли суперпользователь на компьютере клиента иметь привилегии суперпользователя сервера для того, чтобы читать защищённые файлы, находящиеся на самом сервере. В файле cfservd.conf необходимо создать список:
control: TrustKeysFrom = ( ip-address/series ) admit: /filetree *.domain.country root=myhost,yourhost /etc/shadow *.domain.country encrypt=true
Во втором примере также можно ограничить доступ к определённым файлам зашифрованными строками, т.е. потребовать, чтобы пользователи использовании безопасное соединение при скачивании файла, дабы предотвратить подслушивание.
Доверие центральное понятие в безопасности любой системы. Открытые и частные ключи помогают доверять другим компьютерам, но только после того как подлинные и правильные общие ключи были безопасно переданы всем, кому необходимо. До того как это произошло, необходимо быть уверенным в подлинности удалённых компьютеров. В рамках политики безопасности cfengine предоставляет инструмент, который определяет, стоит ли осуществлять обмен ключами на доверительной основе или нет, когда удалённые компьютеры впервые устанавливают соединение. Чтобы не доверять ключи вслепую, можно создать файлы обмена ключами вручную, например:
scp /var/cfengine/ppkeys/localhost.pub remote:/var/cfengine/ppkeys/root-IP-number.pub
либо можно назначить установку соединения на определённое время в целях минимизации риска, что спуфер появится на последней стадии передачи ключа конкретному пользователю на конкретный компьютер.
Обратите внимание, что даже такие программы, как ssh, использующие привилегированные порты, сейчас не гарантируют защиты от спуфинга. Привилегированные порты это порты, которые может использовать только суперпользователь. Идея заключалась в том, что соединение через привилегированные порты может устанавливаться только пользователем, которому можно доверять, поскольку только человек с паролем суперпользователя / администратора может использовать такие порты. Сегодня такая идея, как минимум, наивна. Любой может установить свой собственный компьютер, воткнуть вилку в другой и имитировать адрес или пользователя. На сегодняшний день существует настолько много способов атаковать систему, что невозможно с уверенностью знать, с кем установлено сетевое соединение. Единственный способ обеспечить безопасность иметь секретный ключ. Однако если кто-то установил соединение раньше владельца с помощью поддельного ключа и теперь притворяется им, получатель этого не узнает. И это правило применимо к любым программам шифрования.
Безопасное копирование cfaengine не основывается на SSL / TSL (хотя он разделяет некоторые библиотеки нижнего уровня). SSL не походит для системного администрирования, так как её модель безопасности строится на привлечении третьей стороны, например Verisign. Большинство администраторов не готовы платить взнос за регистрацию каждого компьютера своей сети с помощью надёжной третьей стороны. Также cfengine не использует и Secure Shell протокол. Протокол ssh не достаточно подходит для управления системой, поскольку он обеспечивает только одностороннюю аутентификацию пользователя сервером. В то время как cfengine осуществляет взаимную аутентификацию этих сторон, т.е. пользователя сервером и сервера пользователем. Более того, ssh требует, чтобы пользователь вручную получал доверительный ключ, в то время как публичный ключ сторонам неизвестен, тогда как cfengine работает автономно (т.е. без взаимодействия с пользователем). Для подтверждения личности привилегированного пользователя SSh использует принцип соединения с доверенным портом, в то время как cfengine такого предположения не делает.
Cfengine воспринимает все свои операции как блокированные транзакции. Блокировка предотвращает возникновение конфликтов между сосуществующими процессами и он также накладывает определённые ограничения на длительность выполнения программы. Тот факт, что операции заблокированы значит, что несколько программ cfengine могут сосуществовать без каких-либо трудностей. За то, как операции могут устанавливать блокировщики, отвечают два блокирующих параметра. Параметр IfElapsed сообщает операциям, что они могут быть исполнены только по прошествии определённого количества времени с момента последнего выполнения этого действия, что обеспечивает защиту от спама. Параметр ExpireAfter сообщает cfengine максимальную временную продолжительность действия, что обеспечивает защиту от зависших подчинённых процессов.
Под спуфингом понимается попытка замаскироваться под другой компьютер во время осуществления обмена по сети. Программа cfservd, которую можно использовать для передачи файлов или удалённого запуска cfengine, пытается выявить такие попытки с помощью создания двойных обратных тупиков на сервисе имён. Доверенный сервер должен подтвердить, что сокет адрес и имя компьютера на самом деле являются теми, которыми они себя объявляют.
При копировании файлов с источника существует вероятность, что в ходе работы возникнут сбои и взамен останется искажённый файл. Например, в течение копирования файла может переполниться диск, что может повлечь за собой проблемы. Cfengine справляется с этим за счёт копирования в новый файл получающей файловой системы (prefix.cfnew), а затем переименовывает его обратно только в случае успешной передачи. Это гарантирует наличие места в файловой системе и отсутствие проблем с системным соединением или диском в процессе копирования.
В качестве дальнейшей проверки в ходе копирования cfengine позволяет определять приемлемые ограничения на размеры файлов. В конце концов, порой ошибки могут быть абсолютно не связаны с работой в cfengine. Например, файл с паролем мастера мог стать по неким причинам пустым или был заменён бинарным по глупой ошибке. Создав проверку предполагаемого размера файла в ходе копирования и вставив это в команду copy, можно избежать установки повреждённого файла и вывода проблем с локального на глобальный уровень.
Существует определённая опасность в запуске скриптов из программ, которые работают с привилегиями суперпользователя. Как правило, как правило, команды shell запускаются исполнением с помощью команды /bin/sh-c. Главная проблема заключается в том, что она оставляет возможность для различных атак. Одним из примеров является обман, в результате которого shell начинает исполнять другие программы, который становится возможным за счёт использования IFS переменной, чтобы толковать / как разделитель. Можно попросить cfengine запускать программы непосредственно, не прибегая к посредничеству shell, если присвоить переменной useshell значение ложь. Недостаток заключается в отсутствии возможность использовать директивы shell, такие как | или > в пользовательских командах. Директива owner=uid исполняет команды shell как для особенного пользователя, позволяя осуществлять безрпасный запуск скриптов без привилегий корня.
Cfengine является очень удобным инструментов для внедрения, контроля и поддержания firewall. Он даёт возможность управлять тем, какие программы должны быть под защитой firewall, а какие нет. Также можно управлять полномочиями по доступу к файлам, процессами и множеством других вещей, которые позволяют создать конфигурацию абсолютно надёжного компьютера. Если снабдить все важные программы ссылками и читать только носитель, то можно не только контролировать целостность компьютера, но всегда быть уверенным, что cfengine работает абсолютно правильно.
Одним из сильных качеств cfengine является использование им классов для определения систем из одного или нескольких файлов. Многим администраторам также хотелось бы, чтобы демон cron работал подобным образом. Одним из способов установить cron из глобальной конфигурации является использование функции editfiles , существующей в cfengine, для редактирования файлов cron отдельно друг от друга. Но гораздо лучше использовать классы времени cfengine для работы в качестве пользовательского интерфейса для cron. Это позволяет иметь один центральный файл cfengine, в котором находятся все задания cron в системе, при этом все замечательные функции, предоставляемые cron, остаются доступны. Как применяются все основные преимущества?
Главная идея, лежащая в основе этого принципа, - установить регулярную задачу cron на каждой системе, которая с определённой частотой запускает cfagent. Каждый раз при запуске cfagent он оценивает классы времени и выполняет команды shell, заданные в его файле конфигурации. В таком случае cfagent используется в качестве упаковщика(wrapper) для скриптов cron, поэтому классы cfagent можно использовать для управления заданиями на множестве компьютеров. Классы времени в cfagent, по меньшей мере, настолько же мощный инструмент, как и возможности cron по спецификации времени, поэтому использование такого метода не повлечёт каких-либо ограничений. См. раздел 5.3 [Создание гибких классов времени], стр.60. Единственный недостаток заключается в дополнительных издержкахна анализ конфигурационного файла cfagent.
Для более детального рассмотрения вопроса, представим, что следующий файл crontab устанавливается на каждый компьютер сети:
# # Global Cron file # 0,15,30,45 * * * * /usr/local/sbin/cfexecd -F
Структура cfagent.conf должна отражать принципы, согласно которым требуется осуществлять запуск задач в системе. Необходимо активизировать соответствующие задания и отключить неиспользуемые в соответствии с временем суток. Это можно сделать тремя способами:
action: Hr00.Min10_15||Hr12.Min45_55:: Command
control: Hr00:: # Action-sequence for daily run at midnight actionsequence = ( sequence ) !Hr00:: # Action-sequence otherwise actionsequence = ( sequence )
import:
Hr00:: cf.dailyjobs
any:: cf.hourlyjobs
Последний вариант является самым эффективным из всех трёх, поскольку cfagent даже не приходится тратить время, анализируя файлы на наличие тех действий, которые заранее являются ненужными.
Проблема, заключающаяся в запуске всех cfagent в одно и то же время, используя один cron файл, состоит в том, что это может привести к разногласиям или неэффективной работе. Например, если сто cfagent вдруг захотят одновременно получить копию файла из главного источника, это приведёт к огромной нагрузке на сервер. Такую ситуацию можно предотвратить, если ввести временную задержку, уникальную для каждого компьютера и не превышающую заданного интервала. Cfagent использует алгоритм хэширования для генерации числа минут от нуля до заданного максимального значения. Это выглядит примерно так:
# Put this in update.conf, so that the updates are also splayed control: SplayTime = ( 10 ) # minutes
Если такое число не равно нулю, то после анализа своего файла конфигурации и определения времени cfagent перейдёт в режим ожидания. Каждый механизм будет переходить в такой режим на разные промежутки, которые не превышают заданного в минутах времени. Механизмы хэширования, основанные на полностью уточнённых именах компьютеров, используются для определения уникального промежутка для каждого из них. Чем короче интервал, тем более сконцентрировано будут работать компьютеры. Чем длиннее интервал, тем менее нагруженным окажутся серверы. Такое распределение времён работы позволит уменьшить нагрузку на серверы, даже если они пришли из неподчинённых доменов, но работают по тем же cron принципам.
Каждый раз при запуске cfagent определяет время по часам системы и задаёт значение следующим классы времени и даты:
Yrxx: : | Текущий год, например, Yr1997, Yr2001. Как правило, этот класс используется не часто, но он может пригодиться, чтобы включить индикаторы Нового Года или подчистить системы перед новым тысячилетием. |
`February'. | Эти классы можно использовать, например, для определения сроков летних каникул студентов, или для проведения дополнительной очистки систем,чтобы поддерживать определённые административные функции на протяжении конференции. |
Day:: | День недели может использоваться, как класс, например, `Monday', `Sunday'. |
Dayxx:: | День месяца (дата) может использоваться для того, чтобы выделить что-то по дате. Например, первый день каждого месяца определяется `Day1', 21ый - `Day21' и т.д. |
Hrxx:: | Час в сутках (24 часа): `Hr00'...`Hr23'. |
Minxx:: | Точная минута запуска cfagent: `Min0' ... `Min59'. Как правило, отдельно этот класс не используется, но они могут комбинироваться для задания произвольного промежутка времени. |
Minxx_xx:: | Пятиминутный интервал в том часу, когда работал cfagent в виде: `Min0_5', `Min5_10' .. `Min55_0'. |
Классы времени, задающие точное время запуска cfagent в минутах, вряд ли будут часто использоваться, поскольку маловероятно, что кому-либо потребуется просить cron запускать cfagent каждую минуту каждый день: ему просто не хватит времени на окончание одной работы перед тем, как быть запущенным снова. Более того, многие факторы могут повлиять на задержку запуска cfagent. Возможность определять точное времени запуска, главным образом, используется для создания составных классов, которые задают произвольные промежутки времени. Для этого необходимо использовать действие group или classes, чтобы создать алиас для групп со значением времени. Ниже приведём несколько нестандартных примеров:
classes: # synonym groups: LunchAndTeaBreaks = ( Hr12 Hr10 Hr15 ) NightShift = ( Hr22 Hr23 Hr00 Hr01 Hr02 Hr03 Hr04 Hr05 Hr06 ) ConferenceDays = ( Day26 Day27 Day29 Day30 ) QuarterHours = ( Min00 Min15 Min30 Min45 ) TimeSlices = ( Min01 Min02 Min03 Min33 Min34 Min35)
В данных примерах значением левой части выражений является логическое объединение элементов в правой части. Это значит, что, если хоть какой-нибудь из классов в скобках будет определён, то и значение левой части тоже будет определено. Таким образом можно понятно и по-разному задавать промежутки времени внутри программы, не используя где-либо операторов | или ..
Как часто необходимо запускать глобальный скрипт cron? Для ответа на этот вопрос необходимо обдумать следующие аспекты:
В cfengine использует грамотные механизмы блокировки и ожидания, которых достаточно для исполнения команд shell, висящих с предыдущих запусков cron, поэтому никаких наложений не произойдёт. См. раздел 6.2.3. [Спам и безопасность]
В данном руководстве слово хост используется для описания одной компьютерной системы, то есть одной машины с именем hostname.
Cfengine инструмент для создания и поддержания работы компьютерных систем. Он состоит из нескольких компонентов:
Cfagent автономный конфигуратор (обязателен)
Cfservd файл-сервер, возможность удалённого запуска (по желанию)
Cfexecd возможность создания расписаний и вывода отчётов (желательно)
Cfenvd возможность выявления ошибок (весьма желательно)
Cfrun способ удалённого запуска cfagent (используется при необходимости)
Cfshow анализ содержимого вспомогательных баз данных (помощник)
Cfenvgraph вспомогательный инструмент для cfenvd (помощник)
Cfkey механизм генерации ключей (запускается единожды на каждом хосте)
Для работы cfagent не требуется установка других программ, но все возможности cfengine станут доступны только после того, как все компоненты будут установлены и используемы должным образом.
Cfengine использует специальный язык, гораздо более высоко уровня, нежели Perl или Shell: одно предложение может запускать несколько сотен операции на нескольких хостах. Cfengine отлично подходит для выполнения множества стандартных системных заданий администрирования и позволяет увеличить его возможности с помощью пользовательских скриптов. Он также может быть использован в качестве клиентской части всей сети для cron. Установка cfengine избавит пользователя от необходимости ручной конфигурации, предоставляя ему больше свободного времени для выполнения других заданий.
Главная задача cfengine предоставить возможность создания единой конфигурации системы, которая позволит определять конфигурацию каждого из хостов сети, причём делать это интуитивно централизовано или децентрализоавано, в зависимости от желания. Интерпретатор работает на каждом из компьютеров пользовательской сети и анализирует master file (или множество файлов). В соответствии с этим файлом проверяется конфигурация каждого хоста. Затем, по запросу пользователя, он автоматически фиксирует любые отклонения от заданной конфигурации. Для конфигурации хостов не нужно отдельно задавать их имена: вместо этого можно ввести определённые характеристики, отличающие один хост от другого. Cfengine использует гибкую систему классов, которая позволяет одним предложением выделить определённую группу хостов.
Cfengine был создан в университетском колледже города Осло из необходимости контролировать процесс накопления различных shell scripts скриптов, используемых для автоматизации процесса поддержания основной системы. Тогда было написано множество скриптов на Perl и shell, выполняющих такие задачи администрирования, как отчистка файлов, нахождение обновлений базы данных, проверка выполняемых процессов и ряд других. Скрипты, написанные на shell очень плохо работают в смешанной среде: синтаксис таких команд различается в зависимости от операционной системы, как и расположение и имена ключевых файлов. На самом деле, отсутствие единообразия в Unix вызывало огромную проблему. Скрипты содержали такое множество тестов, определяющих, на какой операционной системе они выполняются, что в последствии стали настолько громоздкими и трудными для чтения, что практически никто не мог разобраться, какие задачи они выполняют. Другие скрипты запускались только на подходящих для них системах, где их можно было не замечать и просто забыть. Вскоре стало ясно, что идеальным решением стала бы замена такого разрастающегося множества скриптов одним файлом, содержащим всё необходимое для того, чтобы работать на любом хосте сети. Благодаря разработке нового языка, такой файл мог бы скрыть все упомянутые выше тесты, используя систему классов для обозначения операций (обобщённый синтаксис переключатель \ случай) и повышения удобочитаемости. Постоянное совершенствование этой идеи привело к созданию современного cfengine.
Неопытный пользователь cfengine, вероятно, будет пытается проделывать все операции также, как он делал бы это при работе с Perl или в shell. Это не лучший способ работы с cfengine. Пользователю придётся приспособиться к другому образу мышления, который соответствует cfengine. Читая данное руководство, следует помнить, что способ работы cfengine - думать о том, каким должен быть конечный результат, а не о том, каким путём его добиться (работая с Perl и shell необходимо описывать скорее действия, а не результат).
Последующие главы данного руководства предполагают, что пользователь немного знаком с BSD и системами UNIX System V, а также является опытным пользователем C shell (csh) или Bourne shell (sh), или других производных. Опытный системный администратор может опустить первые главы и сразу перейти к рассмотрению примеров в разделе Примеры конфигурационных файлов в Дополнении к руководству. Такой способ, возможно, является самым быстрым для начинающих. Если же Вы не настолько хорошо знакомы с системным администрированием и хотели бы изучить всё более детально, тогда переходите к следующим главам...
Системный администратор небольшой сети с несколькими рабочими станциями или, например, всего лишь с одной центральной системой, скорее всего, не будет создавать большой проблемы из администрирования системы. В конце концов, для них всегда проще оказывается вручную настроить все параметры при возникновении каких-либо проблем: в одном месте создать ссылку, в другом написать скрипт и т.д., и, скорее всего, они не считают нужным записывать все проделанные ими операции, потому что знают, что всегда проще настроить всё в следующий раз снова, и так по кругуНо сеть имеет тенденцию расширяться и (прежде чем это узнать), существует пять различных типов операционных систем, каждую из которых необходимо конфигурировать по-своему, для каждой из систем нужно создавать патчи. В результате, не всегда можно вспомнить, настроен ли уже тот или иной хост в другом конце зданияТакже довольно быстро становиться понятно, что BSD или System V не настолько придерживаются единых стандартов, насколько можно предполагать. Ни один простой скрипт, работающий на одной из систем, не будет работать на другой без тщательного анализа и неоднократного тестирования. Попытка написать скрипт, который поможет автоматизировать эти процессы, заканчивается огромным количеством условий ifthen...esle, глядя на которые становиться очень сложно разобраться в том, что же на самом деле происходит.
Для того, чтобы осуществлять систематичное управление сетью, в которой работает множество различных операционных систем, необходимо разработать определённые правила внесения изменений, что гораздо разумнее, нежели переустанавливать систему. В довершении всего, было бы настоящей трагедией потерять весь результат, полученный после многочасовой ручной настройки системы, из-за выхода диска из строя через неделю или даже через год, когда администратор уже забыл всё, что ему приходилось делать. Обновление программного обеспечения операционной системы может привести к потере так тщательно разрабатываемой конфигурации. В таком случае необходимо иметь отдельную запись обо всех патчах, требуемых для каждой из систем сети, запись которую можно сравнить с состоянием каждого хоста в любой момент времени и которую соответствующий механизм сможет использовать, для того, чтобы зафиксировать любые отклонения от стандарта.
Идея, лежащая в основе cfengine - сконцентрировать внимание на нескольких ключевых аспектах базового системного администрирования и создать язык, на котором программы конфигураций станут оптимально понятными. Он избавляет от необходимости неоднократного тестирования за счёт возможности организовывать сеть по классовому принципу. С помощью одного конфигурационного файла (или набора файлов) возможно определять, как следует конфигурировать сеть, а затем cfengine будет анализировать такой файл и выполнять все инструкции, сообщая о возникающих в процессе ошибках.
может оказаться полезным.
Одной из привлекательных черт BSD и System V является тот факт, что они конфигурируются через понятные для чтения текстовые файлы. Чтобы добавить в систему нового пользователя необходимо редактировать /etc/passwd, чтобы добавить новый диск /etc/fstab и т.д.. Многие другие операции также выполняются с помощью текстовых файлов. Устанавливая новую систему впервые или обновляя старую, неизбежно приходиться сталкиваться с необходимостью редактировать множество текстовых файлов. В некоторых случаях, при внесении каких-либо изменений, приходиться добавлять одну и ту же строчку в один и тот же файл для каждой системы сети. Именно поэтому автоматизирование этого процесса оказалось бы весьма полезным, так как избавило бы администратора от необходимости вручную загружать каждый файл через текстовый редактор и самостоятельно вносить изменения. Это одна из тех операции, которую позволить автоматизировать cfagent. В операционной системе Windows данные конфигурации хранятся в базе конфигурации системы (registry). При использовании правильных инструментов cfagent также позволяет редактировать эту базу, но это потребует большей осторожности.
Каждый из компьютеров, подключённых к сети Ethernet, использующей протоколы TCP/IP, должен иметь так называемый сетевой интерфейс. Такой интерфейс должен быть сконфигурирован до того, как будет использован. Обычно, это делается при помощи команд ifconfig. Но cfagent также может выполнить проверку и автоматическую конфигурацию.
В ходе конфигурации сети необходимо сообщить hardware интерфейса Интернет (IP) адрес системы для того, чтобы он знал, на какие поступающие пакеты данных необходимо обращать внимание. Это включает в себя задание способа интерпретации входящие данных, включает в себя установку маски сети (см. ниже), чтобы задать интерфейсу правила интерпретации получаемых адресов. Наконец, необходимо указать широковещательный адрес, который будет использоваться для одновременной рассылки сообщений на все хосты сети (см дополнение к руководству).
Большинство функции Cfagent в основном предназначены для работы с хостами, использующими статичный IP. При использовании DHCP клиентов использование функций сетевой конфигурации не требуется.
Скорее всего первым желанием при работе с сетью (после формирования впечатления от World Wide Web) станет предоставление доступа к файлам всем или некоторым хостам сети, вне зависимости от их местонахождения. Другими словами, если имеется диск, физически подключённый к хосту А, то задача состоит в том, чтобы сделать содержимое этого диска доступным для хостов B, C, D и т.д. NFS (the Network FileSystem) реализует такую возможность.
Этот процесс реализуется с помощью filesustems. Filesystem (файловая система) - это одна секция дисковода или одна единица пространства на диске, к которой можно получить доступ через одно логическое устройство /dev/somethingДля того, чтобы сделать файловую систему доступной для других хостов необходимо сделать три вещи:
Только после того, как были выполнены все вышеперечисленные действия, файловая система станет доступна для всей сети. Cfagent помогает сделать выполнение последних двух операции максимально простым. Для редактирования exports файла также можно использовать возможности работы с текстом cfagent, но существуют и другие способы обновить файл exports используя NIS или netgroups, которые здесь не рассматриваются. В случае возникновения сомнении, смотрите часть руководства, посвящённую экспортированию (5). Некоторые сайты предпочитают избегать использования файловых систем NFS, с целью избежать зависимости одного устройства от другого. Вместо этого они предпочитают создавать локальные копии файлов на удалённом компьютере. Как правило, для этого используются такие программы, как rdist, но для такого копирования файлов также можно использовать cfagent (см. раздел 6.2.1).
Существуют два способа установить адрес в Интернет (так называемый, IP адрес). Первый использовать текстовый адрес, например, www.freesource.ru, другой с помощью цифр 217.112.37.140. К сожалению, прямого соответствия между этими числовым и текстовым адресами не существует, поэтому требуется сервис (называемый DNS), который отождествляет одну форму с другой.
Такой процесс осуществляется одним или несколькими специальными хостами сети, называемыми серверами преобразования имён. Каждый из хостов должен знать, как подключиться к такому серверу или он, скорее всего, зависнет при первой попытке присвоить ему IP адрес. Определить способ подключения к серверу преобразования имён можно редактируя текстовый файл /etc/resolv.conf. В этом файле должны содержаться доменное имя домена и список возможных серверов преобразования имён, к которым может выполняться подключение, в порядке приоритета. Так как данный файл является специальным файлом, обязательным для каждого хоста, то использование основных возможностей по работе с текстовыми файлами cfagent не потребуется. Можно просто определить сервера преобразования имён для каждого хоста в файле cfagent , а cfagent уже сам автоматически выполнит редактирование /etc/resolv.conf. Если позже потребуется поменять приоритеты серверов преобразования имён или редактировать сам список, то простое изменение одной - двух строк в файле конфигурации позволит осуществить автоматическую реконфигурацию каждого из хостов сети без необходимости самостоятельно вносить какие-либо изменения.
Безопасность является важной для любой системы. Учитывая всю занятость администратора, понятно, что иногда он может забыть установить нужные правила доступа к каждому файлу, что может повлечь либо возникновение бреши в системе защиты, либо проблемы с доступом к файлам.
Типичный пример, когда администратор с помощью FTP загружает новый пакет, компилирует его и устанавливает, не вдаваясь в подробности. Но учитывая то, что при загрузке автор и права доступа к файлам в FTP архиве остаются теми же, какими их установил автор программы, то зачастую программное обеспечение остаётся с теми данными, которые были присвоены ему создателем, а не именем какого-то пользователя данной системы. Таким образом, владельцем авторского идентификатора может стать любой пользователь сети, или же наоборот ни один! У файлов должен быть владелец и обычным пользователям они должны быть доступны для чтения, но не для записи.
Например, из-за простой случайности или невнимательности файлы с паролями могут стать доступными для записи всем пользователям. В таком случае под угрозу встанет безопасность всей системы в целом. Cfagent, в свою очередь, позволяет контролировать права доступа, авторские права, существование тех или иных файлов и папок в целом, и при желании, а также корректировать их и уведомлять о них автоматически.
&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;lt;!-- @page { size: 21cm 29.7cm; margin: 2cm } P { margin-bottom: 0.21cmОдна из сложностей работы, связанная с наличием множества различных версий BSD и System V операционных систем состоит в том, что аналогичные файлы не всегда находятся там, где можно ожидать. Они могут иметь разные имена или располагаться в разных папках. Стандартным решением данной проблемы является создание алиаса для таких файлов или указателя с одного имени файла на другое. Такой алиас назвется символической ссылкой.
Создание символических ссылок зачастую является очень удобным. Например, может потребоваться сделать конфигурационный файл отправки почты /etc/sendmail.ct ссылкой на глобальный конфигурационный файл, скажем, /usr/local/mail/sendmail.cf/ для каждого хоста сети, чтобы в дальнейшем редактировать приходилось только один файл. Самостоятельное создание таких ссылок может занять вечность. Cfagent же создаст подобные ссылки автоматически и будет проверять их каждый раз при запуске. Также он может стереть все старые ссылки, которые лежат без дела и не указывают ни на какой существующий файл. При переустановке операционной системы также не возникнет никаких проблем, так как все ссылки определены и сохранены в файле конфигурации cfagent. Ни cfagent ни администратор не забудут их, поскольку вся установка определяется в одной центральном месте.
Cfagent также позволяет создавать жёсткие ссылки на регулярные файлы, но не на какие другие. Жёсткая ссылка, указывающая на символическую ссылку, по сути является жёсткой ссылкой на тот файл, на который ссылается символическая.
Вышеперечисленный материал даёт общее представление о том, для чего может использоваться cfagent. Ниже приведено краткое описание возможностей cfagent:
Как запускать cfagent? Запуск может осуществляться либо с помощью cron, либо вручную. Запускать скрипты и программы cfagent можно с любой частотой. Каждый раз при запуске скрипта, cfengine определяет необходимость выполнения каких-либо действий. В случае, если такой необходимости нет, ничего не будет выполняться. Если cfagent используется для конфигурации и проверки всей системы с центральной базы файлов, то естественней всего периодически запускать cfengine с помощью cron и(или) cfexecd.
Глава посвещена азам работы с Cfengine
Конфигурационный файл cfagent для крупной сети может оказаться длинным и запутанным. Поэтому прежде, чем перейти к деталям, мы попытаемся уйти от сложных вопросов и сосредоточить внимание на самом важном.
Каждая программа или конфигурационный файл cfagent представляет собой список объявлений того, что необходимо проверить и, возможно, настроить. Сначала нужно создать файл `cfagent.conf'. Самый простой, что-то значащий, файл может выглядеть примерно следующим образом:
В приведённом примере проверяется и (при необходимости) создаётся ссылка с`/bin' на `/usr/bin'.# Comment...
control:
actionsequence = ( links )
links:
/bin -> /usr/bin
Рассмотрим этот пример подробнее. В программе cfengine:
В рассмотренном выше простом примере представлены три из описанных типов записей. Секция control: любой программы указывает cfengine на его действия. В данном примере она добавляет в последовательность действий action sequence действие links. Вместо links можно вставить любое другое действие. Самое важное заключается в том, что если в тексте не задана последовательность действий (т.е. action sequence), то cfengine не будет ничего делать. Последовательность действий action sequence задаёт список действий, которые необходимо выполнить cfagent и порядок их выполнения.
Секция links: сообщает cfagent, что далее идёт список ссылок, которые необходимо создать. При создании данной секции необходимо добавить действие links в action sequence, иначе ссылки не создадутся. В данной части можно задавать любое количество ссылок, которые будут созданы в соответствующем порядке, но только если добавить links в action sequence.
В итоге, в файле должны быть:
Теперь проанализируем для чего можно использовать рассмотренный пример. Такая проверка может оказаться полезной в системе SunOS (Solaris), где папка /bin предполагается быть ссылкой. Но в другой системе, где /bin является не ссылкой, а отдельной папкой, cfagent выдаст сообщение об ошибке, говорящее, что /bin существует и не является ссылкой. Отсюда следует вывод, что при желании использовать cfagent для создания одой программы, которая смогла бы работать на всех хостах любого типа, необходимо каким-либо образом ограничить создание данной ссылки, чтобы оно осуществлялось только на системах SunOs. Для этого можно сделать следующее:# Comment...
control: actionsequence = ( links ) links: sun4:: /bin -> /usr/bin # other links osf:: # other links
Имена, оканчивающиеся на двойное двоеточие, называются классами и используются для введения ограничений на выполнение конкретного действия. Таким образом, действие будет совершаться только в том случае, если хост, на котором запускается программа, является членом данного класса. Знакомому с C++, такой синтаксис может напомнить процесс определения классов в C++. Принцип работы классов такой: cfagent сам определяет принадлежность классам sun4, sun3, osf и т.д.. Например, если файл запущен на хосте с операционной системой OSF, то данный хост автоматически становиться членом класса osf. Так как хост не может принадлежать более, чем к одному из определённых видов, то это выделяет его среди различных типов операционных систем и создаёт скрытые команды ifthenelse.
Таким образом в cfagent осуществляется процесс принятия решений. Главная идея состоит в том, что действия совершаются только тогда, когда они описаны в том классе, к которому относиться хост, на котором запущена программа. Подробнее о классах будет рассказано в следующей главе.
Рассмотрим, как добавить новое действие в последовательность action sequence:# Comment...
control: actionsequence = ( tidy links ) links: /bin -> /usr/bin tidy: /tmp pattern=* age=7 recurse=inf
Здесь добавлено новое объявление tidy:, которое удаляет файлы. В данном примере в папке /tmp производиться поиск файлов типа *, которые не открывались более семи дней. Поиск таких фалов распространяется рекурсивно на все подпапки данной директории.
Для того, чтобы запустить данной действие, в последовательность action sequence необходимо добавить слово tidy, в противном случае оно не будет выполняться. Важно, что несмотря на то, что links: были объявлены перед tidy:, порядок в action sequence говорит о том, что выполняться это действие будет после tidy:.
Описанная структура может быть использована для создания файла конфигурации или скрипта.
Для того, чтобы обобщить всё сказанное в предыдущем разделе, приведём образец типичной программы конфигурации cfagent. Различные секции описаны в том порядке, который, вполне вероятно, будет использоваться в action sequence.
Отдельное объявление секции в программе может выглядеть следующим образом:
action-type: class1:: список действий... class2:: список действий...
Тип действия может задаваться одним из зарезервированных слов:
groups, control, copy, homeservers, binservers, mailserver, mountables, import, broadcast, resolve, defaultroute, directories, miscmounts, files, ignore, tidy, required, links, disable, shellcommands, strategie seditfiles, processes
С синтаксической точки зрения, для cfagentне важен порядок, в котором объявлены действия, но некоторые из перечисленных выше действий определяют информацию, к которой в дальнейшем, возможно, потребуется обращение. Все переменные, классы, группы и т.д. должны быть определены до их использования. Таким образом, для секций первой строчки данного списка вполне разумно придерживаться описанного порядка.
Не стоит путать порядок, в котором определяются секции, классы и т.д. с порядком, в котором они исполняются. Этот порядок устанавливается в actionsequence(см.примечания к руководству). Скорее всего, эти порядки будут максимально совпадать.
Для полноты приведём окончательное краткий вариант структуры весьма обобщённой конфигурационной программы cfagent. На формат и использование пространства не действует никаких ограничений, хотя всегда желательно оставлять пустое место до и после скобок при определении переменных.
################################################################## # # Пример структуры # groups:
group1 = ( host host ... ) group2 = ( host host ... ) ...
##################################################################
control:
class::
site = ( mysite ) domain = ( mydomain ) ...
actionsequence = ( action name .... )
mountpattern = ( mountpoint ) homepattern = ( wildcards matching home directories )
addinstallable = ( foo bar ) addclasses = ( foo bar )
##################################################################
homeservers:
class:: home servers binservers: class:: binary servers mailserver: class:: mail server mountables: class:: list of resources
##################################################################
import:
class:: include file class:: include file
##################################################################
broadcast:
class:: ones # or zeros / zeroes
defaultroute:
class:: my-gw
##################################################################
resolve: any:: list of nameservers
Как распространить конфигурацию на несколько хостов, если она определена на одной центральной машине? Простейшее решение - использовать cfengine для распространения конфигурации на разные хосты. Для этого используется отдельный конфигурационный файл. Почему?
Что может случиться, если допустить ошибку (например, синтаксическую) в конфигурации, которая передастся на каждый хост? Тогда ни один из этих хостов не сможет запустить cfengine и, следовательно, загрузить исправленный файл конфигурации. Вся установка будет сорвана. Для того, чтобы избежать такой ситуации, для копирования файлов и двоичного кода на каждый хост используется отдельный файл конфигурации. Такая конфигурация должна быть простой и почти никогда не подвергаться редактированию: главным здесь является надёжность.
Файл update.conf может иметь примерно одну и ту же форму для всех сайтов и выглядеть примерно следующим образом:
####### # # BEGIN update.conf # # Этот скрипт распространяет конфигурацию, простой файл, так что # если в главном config есть синтаксические ошибки, мы по-прежнему можем # распространять правильную конфигурацию, даже если # главный config не будет анализироваться. Он читается и запускается # до анализа главного config. # ####### control:
actionsequence = ( copy tidy ) # Оставьте это постоянным
domain = ( iu.hio.no ) # Необходимо для удалённого копирования
# # Какой из хостов является главным для откачки конфигурации? #
policyhost = ( nexus.iu.hio.no ) master_cfinput = ( /masterfiles/inputs )
# # Некоторые удобные переменные #
workdir = ( /var/cfengine ) cf_install_dir = ( /usr/local/sbin )
# Избежать спор серверов
SplayTime = ( 5 )
################################################################## #` # Убедитесь, что существует локальная копия конфигурации и # самый важного двоичного кода на случай, если соединение отсутствует # например, для мобильных станции или DOS атак # copy: $(master_cfinput) dest=$(workdir)/inputs r=inf mode=700 type=binary exclude=*.lst exclude=*~ exclude=#* server=$(policyhost) $(cf_install_dir)/cfagent dest=$(workdir)/bin/cfagent mode=755 backup=false type=checksum $(cf_install_dir)/cfservd dest=$(workdir)/bin/cfservd mode=755 backup=false type=checksum $(cf_install_dir)/cfexecd dest=$(workdir)/bin/cfexecd mode=755 backup=false type=checksum
##################################################################
tidy: # # В этой директории Cfexecd сохраняет вывод. # Убедитесь, что мы не создавали файлов! # $(workdir)/outputs pattern=* age=7 ####### # # END cf.update # #######
Для организации удалённой рассылки с центрального сервера необходимо запустить cfdervd на хосте, с которого должна копироваться конфигурация. Кроме того, необходимо обеспечить возможность доступа к хостам, на которые предполагается выполнение загрузки. Ниже приведён простой стартовый файл, который выполняет данные действия:
#########################################################
#
# Это файл кончигурации cfservd config file, используемый для серверской
# части cfengine, для удалённой рассылки и управления
# за тем, как cfengine использует программу cfrun.
#
#########################################################
control:
domain = ( iu.hio.no )
cfrunCommand = ( "/var/cfengine/bin/cfagent" )
any::
IfElapsed = ( 1 )
ExpireAfter = ( 15 )
MaxConnections = ( 50 )
MultipleConnections = ( true )
#########################################################
grant:
# Обеспечивает доступ ко всем хостам на example.org.
# Файлы должны быть максимально понятны
/masterfiles/inputs *.example.org
# Убедитесь, что есть разрешение на выполнение cfrun
/var/cfengine/bin/cfagent *.example.org
########
#
# END cfservd.conf
#
########
Куда необходимо помещать файлы? Для организации хранения файлов в зависимости от преследуемой цели можно использовать три различных места:
Хранилище, контролируемое версией, для создания, проверки и внесения изменений в файлы. Как только версия одобрена для выпуска, главные файлы должны быть перенесены в область публикации, то есть в `/usr/local/masterfiles/cfengine/inputs' на `masterhost'.
Централизованное расположение, в котором осуществляется публикация изменённых и протестированных конфигураций. Это буферное хранилище, из которого каждый клиент будет загружать новые и проверенные версии главной конфигурации, например `/usr/local/masterfiles/cfengine/inputs' на masterhost'. Данное расположение служит как буфер для хранения между тестируемыми и готовыми файлами.
Рабочая папка. Здесь хранятся готовые файлы. Как правило, это частная папка, где cfagent предполагает найти свои файлы конфигурации, `/var/cfengine/inputs'. Задача update.conf состоит в копировании в данную папку из главного хранилища.
Модули и методы, как правило, хранятся в отдельной от входных файлов папке, поскольку им требуется директория с особыми правами доступа для выполнения. Такой способ организации весьма полезен. Поскольку update.conf помещает главные версии в нужную папку (обычно /var/cfengine/modules/) на локальном зосте, то всё будет выполнено правильно.
Не стоит пытаться копировать файлы непосредственно из папки контроля версий, так как это может привести к рассылке недоработанных или тестируемых файлов на все хосты.
# Пример update.conf
control:
master_cfinput = ( /usr/local/masterfiles/cfengine/inputs )
workdir = ( /var/cfengine )
copy:
# Копирование из bullet 2 в bullet 3
$(master_cfinput) dest=$(workdir)/inputs
r=inf
mode=700
type=binary
exclude=*.lst
exclude=*~
exclude=#*
server=$(policyhost)
trustkey=true
$(master_modules) dest=$(workdir)/modules
r=inf
mode=700
type=binary
exclude=*.lst
exclude=*~
exclude=#*
server=$(policyhost)
trustkey=true
Cfagent выполняет операции только по запросу. Во время работы он выводит какие-либо сообщения только в случае обнаружения ошибки. Он выполняет действия, только определённые в последовательности действия action sequence.
Однако, при желании cfagent можно настроить на режим диалога. Его можно запускать с рядом параметров командной строки (см. приложение к руководству). При запуске программы с параметрами -v или --verbose cfagent будет выводить сообщения о выполняемых им действиях. Режим диалога также поддерживает вывод определённых предупреждений о возникающих проблемах, поэтому он является удобным механизмом для выявления и устранения ошибок.
При желании cfagent может осуществлять проверку различных параметров, например, временной зоны или имени домена. Для проверки подобных вещей, он должен получить некоторую информацию от пользователя. Все параметры и переключатели, вносящие изменения в ход работы cfagent, определяются либо в командной строке, либо в секции control: контрольного файла. Для этого используются некоторые специальные управляющие переменные. Приведём короткий пример:
control:
domain = ( example.org ) netmask = ( 255.255.255.0 ) timezone = ( MET CET )
mountpattern = ( /mydomain/mountpoint )
actionsequence = ( checktimezone # check time zone netconfig # includes check netmask resolve # includes domain mountinfo # look for mounted disks under mountpattern )
Для того, чтобы включить режим диалога, необходимо запустить cfagent с соответствующей опцией командной строки --verbose или -v.
Следует обратить внимание на то, что установка значений имеет свой синтаксис: имя переменной, знак равенства, значение, записанное в скобках. Таким образом выражению, стоящему слева от знака равенства, присваивается значение, стоящее справа. На этом этапе может возникнуть ряд вопросов, которые будут рассматриваться в процессе и в последующих главах.
Прежде чем завершить краткий обзор управляющих параметров, стоит дать определить mountpatter, описанный выше. Он определяет директорию, в которой cfagent предполагает найти установочные диски(mounted disk). Подробнее об этом будет рассказано в дальнейшем, но пока стоит отметить, что такое определение может показаться весьма непродуманным и неудобным. Гораздо лучше было бы использовать переменные для задания пути к mounted filesystems. Естественно, такая возможность существует.
Кратко проанализировав возможности cfagent, перейдём к рассмотрению примеров и посмотрим, как может выглядеть окончательная программа (см. приложение к руководству). Если на данном этапе у Вас не возникло никаких вопросов, то Вы можете бегло просмотреть остальные части данного руководства и сосредоточить внимание только на непонятных моментах. Следующие главы рассматривают некоторые вопросы более детально.
Запуск cfagent может осуществляться несколькими способами. Приведём несколько примеров:
host% cfagent host% cfagent --file myfile host% cfagent -f myfile -v -n host% cfagent --help
В первом примере (команда по умолчанию, без аргументов) cfagent начинает искать файл cfagent.conf в папке, на которую указывают переменные среды CFINPUTS или /var/cfengine/inputs по умолчанию, и затем извлекает его, не выдавая никаких сообщений. Вторая команда производит чтение файла myfile, также не выдавая никаких сообщений. Третья работает в режиме диалога, а параметр -n устанавливает запрет на выполнение каких-либо действий за исключением вывода сообщений об ошибках. В последнем примере, cfagent выведет список своих параметров командной строки.
Полный список параметров приведён в кратком обзоре в начале руководства и также доступен при указании параметра -h (см.приложение к руководству).
Помимо запуска cfagent с помощью имени файла, его файлы также могут интерпретироваться в качестве скриптов, если запустить его со стандартной shell line (скрытой строкой):
#!/usr/local/sbin/cfagent -f # # My config script #
Здесь предполагается, что cfengine установлен в директории `/usr/local/sbin'. Добавление подобного заголовка в первую строку программы и запуск файла с помощью chmod shell command, позволит осуществлять запуск программы по имени, то есть не упоминая никоим образом cfagent.
Если вы впервые работаете с cfengine, то мы советуем проверить все программы с параметром -n перед тем, как полагаться на Вашу систему, по крайней мере, пока вы не познакомитесь с работой cfengine. Использование данного параметра позволит видеть, что cfengine собирается делать, не принимая в данном процессе никакого участия.
После успешной работы с cfengine, возможно потребуется запускать его в системе по меньшей мере один раз в течении часа. Этого можно легко добиться, если вставить следующую строку в корневой файл crontab каждой системы:
0,30 * * * * /usr/local/sbin/cfexecd -F
Этого достаточно, чтобы гарантировать запуск cfengine. Все получаемые в ходе этого процесса результаты будут храниться в `/var/cfengine/outputs'. Кроме того, вставка в файл cfagent.conf следующей строки позволит системному администратору получать e-mail сообщения о получаемых результатах:
control: smtpserver = ( mailhub.example.org ) # site MTA which can talk smtp sysadm = ( mark@example.org ) # mail address of sysadm
Данным переменным необходимо присвоить соответствующие значения. Ещё один, дополнительный, способ запуска cfengine запустить программу cfexecd с демонами (без -F) (daemon mode option). В таком режиме демон будет находиться в пассивном состоянии и активизироваться только согласно расписанию. Расписание по умолчанию - осуществлять запуск один раз в час (что соответствует Min00_05). Следующие модификации в cfagent.conf позволят демону будет запускать cfagent каждые пол часа:
control: # Когда cfexecd в режиме демона должен запустить cfagent? schedule = ( Min00_05 Min30_35 )
Стоит обратить внимание, что задание времени относится к базовым временным классам cfengine (см. раздел 5.3, [Создание гибких временных классов], стр 60). Несмотря на то, что одного из этих методов достаточно, параллельное использование cron и cfexecd не приведёт к возникновению проблем. Блокирующие механизмы cfagent исключают возможность возникновения конфликтов.
Остальные компоненты cfengine могут запускаться непосредственно cfagent:
processes:
"cfenvd" restart "/usr/local/sbin/cfenvd" "cfservd" restart "/usr/local/sbin/cfservd"
Обратите внимание, что для запуска cfexecd с помощью cfengine необходимо сделать следующее:
processes: "bin/cfexecd$" restart "/usr/local/sbin/cfexecd"
Важно по возможности использовать в совпадающих утверждениях регулярное выражение в качестве специального (в данном примере путь к программе и регулярное выражение metacharacter $, обозначающее конец строки), поскольку пустые строки зачастую могут соответствовать совершенно неожиданным процессам. Например, использование cfexecd самого по себе будет также соответствовать процессу, вызываемому cfagent F, который обнаружиться как /var/cfagent/bin/cfagent Dfrom_cfexecd в таблице процессов
Каждый раз при поиске файлов cfengine выясняет, является ли имя файла абсолютным (то есть начинающимся с /, например, /usr/file), лежит ли этот файл в той же директории, где запускается cfengine, или его необходимо искать в другом месте.
При использовании абсолютного имени файла (то есть, начинающееся с /), как в командной строке с помощью f, так и в секции import программы, cfengine доверяет ему и воспринимает буквально. Если же имя файла определено просто как . или -, то cfengine читает его входные данные из стандартного ввода.
Если запустить cfengine без указания аргументов (то есть имя файла по умолчанию cfagent.conf) или определить файл, не написав / вначале в секции import, то значение переменной среды CFINPUTS приписывается в начало имени файла. Это позволяет хранить конфигурацию в стандартном месте, на которое указывает CFINPUTS. Например,
host# setenv CFINPUTS /usr/local/masterfiles/cfengine/inputs host# cfagent -f myfile
В данном примере, cfengine будет пытаться открыть файл myfile в директории `/usr/local/masterfiles/cfengine/inputs. Если для CFINPUTS не установлено никакого значения, то местом по умолчанию считается доверенная директория cfengine `/var/cfengine/inputs'.
Начинающему работать с cfengine может быть не до конца понятно, как его можно использовать. Ниже приведены несколько подсказок от доктора Дэйстрома о том, как можно быстро производить необходимые операции.
Запускайте cfengine из cron на всех системах каждый час. Убедитесь, что определены все длинные задания или задания, которые не нужно выполнять. Чаще всего это делается с помощью time class, который предотвращает постоянное выполнение заданий (см. главу 5 [Использование cfengine в качестве front-end для cron], стр. 59).
Запуск cfengine из cron значит, что он может работать параллельно в нескольких системах. Для того, чтобы cfengine начал работу на одном хосте, он не должен ждать окончания работы cfengine на другом.
Установите cfservd на всех системах для возможности удалённого запуска cfengine. Это предоставляет возможность быстрого внесения изменений на все системы с помощью cfrun. Необходимо тщательно продумать, кому стоит предоставлять права на запуск cfengine из сети (см. раздел 6.3. [Конфигурация cfservd], стр. 68). Установите cfservd.conf соответствующим образом. Этот демон также может быть использован для предоставления прав на удалённое копирование файлов.
Cfrun периодически анализирует все хосты и выдаёт объединённый пронумерованный список проблем по всем хостам. Недостаток cfrun заключается в том, что каждый хост должен ждать своей очереди.
Не забудьте добавить cfservd в сценарий запуска системы или в inittab, чтобы он запускался при начальной загрузке системы.
Добавьте все хосты в файл cfrun.hosts, вне зависимости от того, являются они главными серверами или другими клиентами. Блокирующий механизм предотвратит возникновение глупых ошибок (см. раздел 6.2.5 [Тупики и неконтролируемые петли], стр. 67). Cfengine сможет решить их. Cfrun позволит осуществлять удалённый запуск cfengine на тех группах хостов, которые удовлетворяют списку классов cfengine.
После установки всех компонентов вся дальнейшая работа сведётся к простому редактированию файлов конфигурации и просмотру результатов.
Данная глава посвящена созданию стратегий создания единой конфигурации сайта для всей сети.
Для того, чтобы с пользой использовать все инструменты администрирования системы, необходимо точно определить ожидаемые результаты и действия, которые Вы готовы предпринять для их достижения. Необходимо решить, что будет считаться допустимым, а что полностью отвергаться. Если этого не сделать, то в случае, когда система начнёт работать не так, как предполагалось, можно остаться в полном непонимании происходящего.
Как показывает опыт, самая успешная стратегия автоматизации подразумевает максимальную простоту во всём. Чем более единообразны и схожи машины (machines) между собой, тем проще осуществлять управление ими и тем более довольны пользователи. Некоторые утверждают, что им необходима настолько высокая степень гибкости, что все машаны должны быть разными. Степень истинности такого утверждения обратно зависит от числа используемых машин и, как правило, оно справедливо только для весьма особенных сред разработки. Обычно есть необходимость только в одном двух специальных компьютерах, тогда как остальные могут быть очень похожи.
Главное в конфигурации сайта обмен и управление ресурсами. Ресурсы включают в себя файловое пространство (filespace), файлы, данные, программы и физические машины. Прежде чем планировать конфигурацию в масштабах сайта, необходимо прежде решить, как всё должно работать.
В остальных частях данной главы содержится ряд советов и подсказок по дальнейшей работе, но стоит запомнить, что на практике необходимо принимать собственные решения.
В случае использования сетевой информационной службы (CИС) в локальной сети, netgroups могут быть уже определены. Они состоят из списков хостов, принадлежащих отдельным владельцам на сайте. Эти группы могут быть использованы и при работе с cfengine. Это значит, что те же группы могут быть использованы в файле /etc/exports как при определении классов и групп монтирования (mount groups).
Netgroup представляет собой список имён хостов или имён пользователей, зарегистрированных в базе данных сетевой информационной службы (СИС) под особым именем. Нас будет интересовать только список имён хостов.
Для создания netgroup необходимо задать список в файле /etc/netgroup на СИС сервере. Пользователю, не являющемуся администратором СИС, придётся просить о возможности создания netgroup. Список хостов netgroup имеет следующую форму:
mylist-name (host1,,) (host2,,) (host3,,) (host4,,) norway-sun4-host (saga,,) (tor,,) (odin,,) foes-linux-hosts (borg,,)
Каждый элемент имеет три записи, но только первый соответствует списку хостов. Полное объяснение значения данных полей представлено в разделе netgroups приложения к руководству.
Netgroups могут быть использованы для обозначения списка имён хостов в системных файлах типа /etc/exports, что уменьшает объёмы текста в данном файле, сводя длинный список в одно имя. Также это значит, что, если при создании групп и классов в cfengine используется тот же список хостов из netgroup, то можно быть уверенным, что один и тот же список используется всегда. В частности, это значит отсутствие необходимости обновлять множество копий списка хостов.
Сейчас netgroups могут использоваться в cfengine с помощью символов + или @+ в секции groups (см. приложения к руководству).
Управление файлами и ссылками может осуществляться несколькими способами. Все действия разделяются на три категории, называющимися files, tidy и links. Первое используется для проверки существования, владения и разрешений к файлам. Второе занимается регулярным удалением ненужных файлов. Третье является менеджером ссылок, который проверяет, создаёт и разрывает ссылки. Мониторинг прав доступа к файлу или владельца может быть установлен как для отдельных файлов, так и для деревьев папок с помощью контролируемой рекурсии. Файлы, не отвечающие определённым критериям, могут быть зафиксированы, то есть автоматически направлены для правки прав доступа, либо о них может быть сообщено системному администратору с помощью предупреждения. Синтаксис таких команд выглядит следующим образом:
files: class:: /path mode=mode owner=owner group=group recurse=no-of-levels action=action
Имя файла или папки является точкой, с которой cfagent начинает поиск файлов. Начиная с неё, поиск файлов продолжается рекурсивно по подпапкам, причём максимальный предел рекурсивного спуска устанавливается директивой recurse, а также различными опциями работы с символическими ссылками и возможностями устройства. Строка mode (mode-string) определяет разрешённый режим работы с файлом (file-mode) (по аналогии с chmod), а владелец и группа могут создавать списки допустимых пользовательских id и id групп. Действие, которое будет осуществляться с файлом, не отвечающим заданному критерию, описывается в директиве action. Это может быть выдача предупреждений или непосредственная фиксация всех или только пустых файлов или папок. Для таких директив существуют отказобезопасные настройки по умолчанию, так что на практике они могут восприниматься как опции. Например,
files: any:: /usr/*/bin mode=a+rx,o-w own=root r=inf act=fixall
где (в краткой форме) будет осуществляться рекурсивный просмотр всех файлов и папок, начиная с папки соответствующей, групповому символу (например, `/usr/local/bin', `/usr/ucb/bin'). По умолчанию, fixall позволяет фиксировать права доступа и владение файлами без последующей выдачи предупреждений.
Единственная проблема, возникающая при использовании символических ссылок, состоит в том, что при удалении файлы, на которые они указывали, могут оставить висящие ссылки. Поскольку cfagent без труда может создавать огромное количество ссылок, то существует опасность, что с течением времени система заполнится ссылками, которые никуда не указывают. Чтобы решить эту проблему, можно установить опцию links=tidy в разделе files (files section). В таком случае cfagent будет удалять любую символическую ссылку, не указывающую на существующий файл (см. приложение к руководству).
Создание символческих ссылок показано на изображении 1, а алгоритм проверки описан в разделе 2. Кроме создания одиночных ссылок, одной единственной командой можно определять и множественные. Команда
links: binaryhost:: /local/elm/bin +> /local/bin
свяжет все файлы в /local/elm/bin с соответствующими файлами в /local/bin. Это предоставляет, кроме всего прочего, простой способ установки пакетов программного обеспечения в регулярные bin директории, не осуществляя при этом контроля за пользовательской переменной PATH. Следующая возможность использует знания cfagent о доступных (монтированных) бинарных ресурсах для поиска соответствий с определёнными ссылками. Подробнее с этим свойством можно ознакомиться в полной документации.
В ходе разработки cfagent стала очевидной необходимость удалять ненужные файлы. Файлы особенно быстро накапливаются в таких областях, как /tmp, /var/tmp. Множество пользователей использует эти области для получения больших ftp-файлов, так что использование ими дискового пространства остаётся незамеченным. Другой пример: всего лишь за последние несколько месяцев появление netscape World Wide Web клиента с возможностями кэширования привело к засорению жёсткого диска в Осло сотнями мегабайтов WWW фалов. Кроме того, постоянное появление файлов ядра(core)1 и скапливание побочных продуктов (файлы с расширениями .o, .log и т.д.) заполняет диски большими файлами, непонятными большинству пользователей. Эта проблема легко решается несколькими строками в конфигурации cfagent. Файлы могут быть удалены, если к ним в течении n дней не совершался доступ. Рекурсивный поиск в таком случае не только возможен, но и крайне часто используется. В следующем примере:
tidy:
AllHomeServers:: home pattern=core r=inf age=0 home/.wastebasket pattern=* r=inf age=14 home/.netscape-cache pattern=cache????* r=inf age=2 home/.MCOM-cache pattern=cache????* r=inf age=2 home/.netscape pattern=cache????* r=inf age=2
все хосты группы AllHomeServers должны осуществлять итерацию по всем пользовательским домашним папкам (использующих групповой символ home) и искать файлы, соответствующие определённым образцам. Cfagent проверяет последнее время доступа к файлам access time и удаляет только те, которые превосходят заданный предел. Поэтому, в данном примере, все файлы ядра(core files) немедленно удаляются, тогда как файлы в подпапке .wastebasket только после того, как они пролежали там без доступа 14 дней и т.д.
Безусловно, системный администратор должен проявлять особенную осторожность при создании правил, которые могут удалять пользовательские файлы. Одна описка может вылиться в правило, которое будет безвозвратно удалять файлы.
Создавая стратегии tidy, необходимо придавать особое значение дублированию (backup). Не стоит удалять файлы до того, как они были продублированы, что обеспечивает подстраховку на самый непредвиденный случай.
В определённой степени,cfagent помогает отслеживать, какие файлы были удалены. При чистке домашних папок пользователей он создаёт журнал регистрации (log файл) всех файлов, удалённых в ходе последней операции tidy. Этот файл называется ~/.cfengine.rm.
Для удаления определённых файлов лишь раз в неделю полезной может оказаться следующая команда:
tidy: AllHomeServers.Sunday:: files to tidy
Ненужные файлы, такие как coreфайлы, могут удаляться каждую ночь.
Внимание! Будьте осторожны при задании операции удаления файлов в cfagent. При написании группового символа типа core*, можно удалить важные системные файлы core.h
Администрирование системы часто требует копирования файлов. Причиной, как правило, является желание распространить копию определённого файла из некой главной точки (master location) и гарантировать, что все копии не являются устарелыми. Другой причиной может быть желание установить программное обеспечение с одной директории (возможно, с CD ROM) на другую.
Cfagent помогает осуществить этот процесс, позволяя копировать отдельные файлы или файловые деревья с одной директории на другую с возможной проверкой прав доступа и владения файлов, чтобы определённым образом упорядочить все копии. Cfagent может проверять файлы двумя способами.
Cfagent позволяет выполнять следующие операции:
Cfagent позволяет проверять существование в системе определённых процессов, посылать им сигналы (например, kill) и, возможно, перезапускать их. Типичным примером использования является отправка cron и inetd сигнала HUP после редактирования их файлов конфигурации, или прекращение ненужных процессов (таких как пользовательские программы, захватывающие огромное количество памяти системы в моменты самого активного использования).
Подробнее об этом можно прочитать в приложении.
Большинство файловых систем, которые потребуется сделать доступными в сети, попадают в одну из двух категорий. В терминологии cfengine они называются домашние директории (home directories) и бинарные директории (binary directpries). Домашние директории место, где хранятся регистрационные каталоги пользователей. Как правило, это директории /home или /users, или какие-нибудь их поддиректории. Бинарные директории место, где хранится откомпилированное программное обеспечение. Такие файлы (которые не относятся к чистым выпускам операционных систем (pure operating system release) ) часто размещаются в директориях /usr/local или просто /local.
В данной главе будут рассмотрены методы использования cfengine для того, чтобы сделать управление файловыми системами NFS наиболее простым.
Использование Network File System (NFS) в условиях крупной рабочей станции требует небольшого планирования. Задача NFS заключается в предоставлении файлов одного хоста другим. Как правило, файловые системы, которые необходимо распределять в сети, разделяются на две категории: бинарные файловые системы (в которых находится откомпилированное программное обеспечение) и пользовательские или домашние файловые системы (где хранятся регистрационные каталоги пользователей).
Самым простым способом разделить ресурсы в сети будет монтирование каждого ресурса (каждой доступной файловой системы NFS) на каждом хосте. Во избежание разногласий каждая файловая система должна иметь уникальное имя. Это первый, но не самый лучший, метод. Опытный пользователь знает, что перекрёстное монтирование (cross-mounting) слишком большого количества файловых систем NFS может вызвать самые разнообразные проблемы.
Cfengine предлагает простой механизм, который поможет выбрать из списка файловых систем NFS только необходимые ресурсы. Затем он автоматически монтирует их и редактирует соответствующие таблицы файловых систем. Он делает это за счёт определения классов хостов. Например, Вам совершенно не нужно монтировать бинарную файловую систему для системы ultrix на систему HPUX. Это совершенно не важно - бинарные ресурсы зависят от архитектуры или жёсткого-класса. Но домашние директории являются независимыми от архитектуры.
Cfengine позволяет создавать список разрешённых серверов для различных хостов так, что для монтирования будут рассматриваться только файловые системы серверов.
Первым шагом на пути превращения файловых систем NFS в ресурсы сети является создание алгоритма наименования так, чтобы каждая файловая система имела уникальное имя, по которому она может монтироваться. Если не решить эту задачу на данном этапе, то может возникнуть ситуация, когда два или более хостов имеют файловую систему, именуемую /usr/local, причём оба эти хоста необходимо монтировать, так как они содержат разное программное обеспечение.
Следующий алгоритм присваивания имён является простым, но весьма полезным1. Всегда существует возможность создания собственного алгоритма, но нижеприведённая информация однозначно говорит в пользу данного. Если точно по описанию следовать данному алгоритму, возможность возникновения проблем с точками монтирования исключена. Он будет детально описан ниже, а сейчас мы приведём несколько основных идей:
Каждая файловая система является данным именем папки, состоящим из трёх частей:
/site/host/contents
Первая директория (которая существует только для создания подходящих точек доступа) является именем локального места. Например, физический факультет университета (располагающийся отдельно) может назвать её physics. Это может быть название компании или что угодно. Вторая часть это имя хоста, к которому физически прикреплено пространство на диске (disk space). Последняя часть название файловой системы. Вот несколько стандартных примеров:
/physics/einstein/local # /usr/local for einstein@physics /physics/newton/u1 # user partition 1 for newton@physics
На машинах, которые являются домашними в локальном делении, лучше создавать ссылку к /usr/local, чем называть файловую систему /usr/local напрямую, так как это позволяет сделать процесс организации всей сети гораздо понятнее.
Стоит отметить, что при указании cfagent монтировать такой ресурс, он автоматически создаст директорию монтирования и легко может сделать ссылку на /usr/local, поэтому эта небольшая дополнительная работа является невероятно простой.
Все правила наименования(name convention) могут быть собраны вместе при определении переменной точки монтирования mountpattern. В рассматриваемой схеме она может быть определена следующим образом:
mountpattern = ( /$(site)/$(host) )
Её значением является имя хоста, открывающего файл, вне зависимости от того, кто это может быть. Эта переменная используется вместе с переменной образца homepattern, которая используется для того, чтобы различать домашние и бинарные директории (см. homepattern в приложении к руководству). Её можно считать одним из условий наименования. В данном тексте для домашних дисков используются обозначения u1 u2 u3. В равной степени можно использовать home1 home2 и т.д. Если имя уникально, то это не имеет значения.
Теперь полный список именованных ресурсов должен быть представлен в списке mountables, который просто является списком всех ресурсов, доступных в сети для монтирования.
После того, как были определены уникальные имена, как cfagent узнает, что необходимо монтировать? Теперь задача состоит в определении списка серверов для каждого класса хостов.
Предположим, что было сделано следующее объявление binserver:
binservers: mygroup.sun4:: einstein newton
Это укажет cfagent монтировать только бинарные ресурсы с хостов einstein или newton на любые хосты типа sun4 группы mygroup. Каждая файловая система, представленная в mountables и не являющаяся домашней директорией, будет монтирована.
Cfagent автоматически отдельно хранит домашние директории и бинарные ресурсы, так как имя-содержимое (contents-name) домашней директории удовлетворяет переменной образца homepattern. См Раздел 4.6.2.[Уникальные точки монтирования файловых систем], стр. 43.
Объявление homeserver:
homeservers: mygroup:: einstein newton schwinger feynman
соответствующим образом будет значить монтирование всех ресурсов домашней директории в списке всех хостов группы mygroup. Естественно, что не нужно проводить различие между типами платформ архитектуры серверов для пользовательских директорий.
В каждом случае cfagent будет монтировать файловые системы, создавать соответствующие директории для точек монтирования и редактировать таблицы файловой системы.
Как только было произведено монтирование ресурса на уникальную директорию, пользователь получает доступ ко всем файловым системам сети. Теперь для того, чтобы монтировать локальную файловую систему на /usr/local, необходимо создать ссылку:
links: any:: /usr/local -> /$(site)/$(binserver)/local
Это значит, что на любом хосте директория /usr/local должна представлять собой ссылку на ближайший локальный ресурс бинарного сервера. Переменная $(binserver), в принципе, может распространяться на любой бинарный сервер в списке. На практике это значит, что cfagent по порядку просматривает список и выбирает первый подходящий ресурс файловой системы.
Может ли это привести к каким-либо противоречиям? Предположим, что мы находимся на хосте einstein и выполняем написанную выше команду. На своём локальном диске хост einstein имеет файловую систему /physics/einstein/local, которая, по факту, является бинарным сервером для сети, поэтому, естественно, что ей не нужно монтировать какую-либо файловую систему NFS. Но это не является проблемой, так как cfagent автоматически воспринимает $(host), как бинарный сервер наивысшего приоритета для любого хоста. Это значит, что у любой локальной файловой системы всегда есть какой-то приоритет.
Тогда как, если хост schwinger выполняет написанную выше команду, он не найдёт локальной системы под названием /physics/schwinger/local, поэтому он будет просматривать список определённых бинарных серверов, найдёт einstein и начнёт всё сначала. Он найдёт einstein, только если все бинарные серверы были монтированы до того, как началось выполнение команды создания ссылок. Это значит, что последовательность действий actionsequence необходимо выстроить таким образом, чтобы все файловые системы были монтированы до того, как созданы какие-либо ссылки.
После недолгой тренировки, модель cfengine может значительно упростить работу с монтируемыми NFS ресурсами.
Внимание: cfengine не пытается экспортировать файловые системы, он только монтирует уже экспортированные. При желании автоматизировать и этот процесс, можно использовать возможности editfiles для добавления записей в /etc/exports (см. editfiles в приложении к руководству). На практике это делать очень сложно и, как правило, нежелательно.
Для примера напишем очень простую конфигурацию для сети с одним сервером, называемым hal, в которой все хосты имеют один тип операционный системы. В таком примере можно полностью избежать использования классов.
control: site = ( univ ) domain = ( univ.edu ) actionsequence = ( mountall mountinfo addmounts mountall links ) mountpattern = ( /univ ) homepattern = ( home? ) binservers: hal homeservers: hal mailserver: hal:/var/spool/mail mountables: hal:/univ/home1 hal:/univ/home2 hal:/univ/local links: /usr/local -> /univ/local
В данном примере рассматривается только один тип хостов, поэтому для каждого из них конфигурация будет одна и та же: не требуется указывать никаких классов. Если просмотреть последовательность действий action sequence, станет видно, что программа в первую очередь монтирует все файловые системы, которые уже определены на каждом хосте. Это делается, чтобы убедиться, что всё, что уже настроено для монтирования, монтировано. Предположим, что на данном этапе не возникает никаких проблем.
Следующим действием mountinfo создаёт список файловых систем, которые были успешно монтированы каждым хостом. Затем вызов addmounts заставляет cfagent проверить, не пропустил ли хост какие-либо файловые системы. В первую очередь cfagent смотрит, какие серверы определены для каждого хоста. В данном примере все хосты сети имеют лишь один сервер hol. Hal является сервером как для бинарных данных, так и для домашнихданных, то есть домашних директорий пользователей. Список mountables сообщает cfagent, какие файловые системы доступны внутри сети для сервера hal. Монтированы могут быть три системы: /univ/home1, /univ/home2 и /univ/local. Cfagent проверяет, монтирована ли каждая из этих файловых систем, и, если нет, он создаёт нужные директории, редактирует необходимые файлы и монтирует файловые системы.
Последним в списке действий идёт links, которое указывает cfagent посмотреть уже определённые ссылки. В данном случае, определена одна ссылка: с /usr/local на монтированную файловую систему/univ/local. Cfagent проверяет и в случае необходимости пытается создать ссылку. Если всё происходит правильно, то в результате каждый хост сети должен иметь по меньшей мере три монтированных файловых системы и ссылку с /usr/local на /univ/local.
Ниже приведён другой простой пример программы для проверки и автоматического монтирования работающего на NFS /usr/local и всех домашних директорий на все хосты небольшой сети. В данном примере существует несколько серверов, поэтому необходимо использовать несколько классов.
have several servers and must therefore use some classes. # # Mounts # control: site = ( mysite ) domain = ( mysite.country ) sysadm = ( mark ) netmask = ( 255.255.255.0 ) actionsequence = ( mountall mountinfo addmounts mountall links ) mountpattern = ( /$(site)/$(host) ) homepattern = ( u? ) # u1 u2 u3 etc.. groups: MyGroup = ( host1 host2 binserver1 binserver2 ) ###################################################################### homeservers: MyGroup:: host1 binservers: MyGroup.sun4:: server1 MyGroup.ultrix:: server2 mailserver: host1:/usr/spool/mail mountables: host1:/mysite/host1/u1 host1:/mysite/host1/u2 server1:/mysite/server1/local server2:/mysite/server2/local ########################################################################## links: /usr/local -> /${site}/${binserver}/local
Предположим, что мы запускает эту программу на хосте host2, который работает на Ultrix. Этот хост принадлежит классу mygroup и жёсткому классу ultrix. Это говорит о том, что его домашним сервером является host1, бинарным сервером server2, и почтовым сервером - host1. Более того, так как homepattern соответствует любой файловой системе, заканчивающейся на u-, в списке mountables он распознаёт две домашних директории и, как следствие, две бинарных директории.
Последовательность действий action sequence начинается с монтирования всех файловых систем, находящихся в настоящее время в таблице файловых систем /etc/fstab. Затем происходит просмотр списка монтированных файловых систем, чтобы определить, что уже монтировано. Поскольку домашним сервером является host1, то хост должен монтировать все домашние файловые системы с этого сервера, поэтому он проверяет только `host1:/mysite/host1/u1' и `host1:/mysite/host1/u2'. Если их не существует, они будут добавлены в /etc/fstab1. Также известно, что бинарным сервером является server1, поэтому следует проверять существование `server1:/mysite/server1/local'. Почтовый сервер также будет проверен и создан в случае необходимости. Затем cfagent ещё раз пытается монтировать все файловые системы, так чтобы были добавлены все новые файловые системы.
Обратите внимание, что в процессе добавления файловых систем в /etc/fstab, cfagent создаёт директории вплоть до и включая точку, где файловые системы должны быть монтированы. Если что-то помешает этому процессу, например, попытка монтировать на верх (mount on top) пустого файла, это приведёт к ошибке.
В заключении идёт раздел создания ссылок и процесс распространения переменных. $(site) раскрывается в mysite. $(binserver) сначала раскрывается в имя хоста (host2), но поскольку /mysite/host2/local не существует, совершается переход к списку бинарных серверов. В результате server1 заменяется на значение переменной $(binserver). Поскольку /mysite/server1/local существует и уже смонтирован, cfagent создаёт ссылку на эту директорию с /usr/ local. Теперь скрипт закончен.
При повторном запуске скрипта всё уже будет сделано, поэтому никаких действий не произойдёт. Если же по каким-то причинам первом запуске пройдёт неуспешно, то повторный также провалиться. В любом случае, он либо сделает работу один раз и целиком, либо выдаст сообщение об ошибке, которая должна быть исправлена человеком2.
Automounter это функция, созданная по принципу демона, которая позволяет заменить статичное монтирование файловых систем NFS динамичной моделью. При запуске automounter файловые системы будут монтироваться, только когда пользователь пытается осуществить доступ к файлу, находящемуся на одной из них. По прошествии заданного промежутка времени (обычно 5 минут) любая файловая система, к которой не был осуществлён доступ, демонтируется. Преимущество такого способа заключается в том, что висящие серверы не влияют на работу хостов, монтирующих их файловые системы, пока не осуществляется доступ к специальным файлам. В обоих случаях для того, чтобы файловые системы можно было монтировать, их надо экспортировать.
В данной главе мы не будем детально описывать работу automounter, а только приведём несколько подсказок для уже посвящённых по тому, как можно использовать cfengine, чтобы упростить и сделать конфигурацию automount более эффективной. Начнём со сравнения работы automounter с работой cfengine по монтированию файловых систем.
Automounter должен быть использован совместно с файлом глобальной конфигурации, распространяемым NIS (the network information service), поэтому все хосты читают одинаковый файл. Может показаться, что все хосты заканчивают монтирование всей файловой системы в базе данных конфигурации automount, но на деле это не так, потому что файловые системы будут монтированы, только если это требуется. Таким образом, система, которой не требуется файловая система, не будет пытаться монтировать её. Более того, существование файла глобальной конфигурации не влияет на то, какие хосты имеют право монтировать определённые файловые системы (что определяется в exports и share соответствующего сервера), поэтому запрос на монтирование неэкспортированной файловой системы приведёт к отказу в доступе. Automount конфигурируется локально на каждом хосте в фалах под названиями /etc/auto_master, auto_direct и т.д.
В статичной схеме монтирования cfengine определяется список бинарных и домашних серверов. В соответствии с этим модифицируется таблица файловой системы. Файловые системы добавляются, только если cfagent сочтёт нужным монтировать их на определённый хост. Главная идея сократить число монтированных файловых систем до тех, которые точно требуются. Вопрос о правах доступа здесь также решается отдельно. Эти файловые системы помещаются в директорию /etc/fstab или её эквивалент в системе.
Automount был создан для решения определённых проблем, которые на данный момент (по мнению автора) лучше решает cfengine. Например, использование карт(maps) хостов в automounter монтирует такие файловые системы, как /usr/local на разных точках монтирования с уникальными именами для каждого хоста во избежание столкновений между именами. В то время как использование cfengine т схемы уникального наименования поможет добиться того же результата гораздо более простым способом и без бессмысленного создания и удаления ссылок, который делает automounter. Более того, алгоритм, заложенный в схеме уникального наименования, лучше выполняется и поддерживается новыми глобальными файловыми системами, такими как AFS И DFS. Единственное преимущество automouter заключается в том, что он не выдаёт раздражающих сообщений об ошибках от зависнувших серверов о том, что NFS сервер не отвечает. В этом отношении вполне разумно использовать прямое монтирование и пространство уникальных имён.
Некоторые системы поддерживают группировку всех пользовательских login (домашних ) директорий под одной директорией, называемой /home или users. Automounter вынужден преодолевать различные трудности, чтобы выполнить эту задачу. При использовании схемы уникальных наименований, типа используемой здесь, это задание становиться элементарным. Необходимо просто назначить монтирование или автомонтирование всех пользовательских директорий, таких как
/site/host/home1 /site/host/home2 ... а затем связать их, как:
/home +> /site/host/home1 /home +> /site/host/home2 ...
Наконец, необходимо помнить, что automount нельзя смешивать с статическими операциями монтирования и демонтированиия. Автоматически монтированные файловые системы имеют приоритет перед статически монтируемыми, но automounter могут возникнуть проблемы, если в процессе его работы вручную монтировать или демонтировать файловые системы.
Очень положительной характеристикой систем BSD и UNIX System V является тот факт, что они сконфигурированы, в основном, с помощью понятных для чтения текстовых файлов. Это делает процесс конфигурации системы несложным, а также упрощает автоматизацию этой процедуры. Большинство файлов конфигурации это состоящие из строк текстовые файлы, что объясняет популярность таких языков программирования, как, например, Perl. Cfengine не пытается соревноваться с Perl и похожими языками. Его встроенные функции редактирования работают на более высоком уровне и созданы для обеспечения скорее понятности, нежели гибкости. К счастью, большинство операций редактирования заключаются во вставке, закомментировании или удалении определённых строк в файле.
Например, некоторые администраторы считают возможность предоставить пользователю детальную информацию о каком-либо объекте потенциально-опасной и хотят отключить её. Это можно сделать следующим способым:
editfiles: { /etc/inetd.conf HashCommentLinesContaining "finger" }
Команды, содержащие слово Comment используются для закомментирования определённых строк в текстовом файле, то есть чтобы скрыть для программы строчку, не удаляя её при этом. Изначально существовало три типа комментариев: стиль shell (решётка) #, %, который использовался в TeX и в системах AIX и стиль C++ //.
Возможен и более гибкий способ комментирования, использующий обозначения, которые сначала объявляют строку - начало комментариев, а затем окончания. Затем одна команда может быть использована, чтобы отменить комментарии. По умолчанию символом строки начала комментариев является # и строка окончания по умолчанию пустая строка. Например, для того, чтобы обозначить комментарии, как в C необходимо написать следующее:
{ file SetCommentStart "/* " SetCommentEnd " */" # Comment out all lines containing printf! CommentLinesMatching ".*printf.*" }
Такие команды редактирования также могут использоваться для наблюдения и управления доступом к корню хоста путём внесения изменений в такие файлы, как .rhosts и установки стандартных переменных окружения в глобальных файлах ресурсов shell, например, для установки временной зоны. Возможность редактирования также можно использовать для того, чтобы обновить или распространить сообщение файла дня (message of the day file), или для конфигурации рассылки почты(см. FAQS и Подсказки в приложении к руководству).
Необычайно полезным сервисом cfagent является возможность редактировать одинаковые файлы, принадлежащие каждому пользователю сети. Например, системному администратору иногда необходимо гарантировать, что пользователи работают в прве яющем логин окружении (sensible login environment). Изменения в системе могут потребовать от всех пользователей объявить, например, новую переменную окружения. Это можно сделать с помощью псевдо-группового символа home. Если написать
{ home/.cshrc AppendIfNoSuchLine "# Sys admin/cfengine: put next line here" AppendIfNoSuchLine "setenv PRINTER newprinter" }
Тогда пользовательские файлы будут один за одним проверяться на наличие определённых строк текста и при необходимости редактироваться.
Файлы загружаются в cfagent и редактируются в его памяти. Они снова сохраняются только при внесении каких-либо изменений. В таком случае старый файл будет сохранён с добавлением к его имени суффикса. При редактировании файлов cfagent выдаёт администратору предупреждения для того, чтобы он мог понять причину, по которой вносятся изменения.
Не нужно путать принцип работы cfagent с работой sed или perl. Некоторая функциональность была скопирована для удобства, но специальные функции создавались из соображений (а) их надёжности и (б) из-за частой необходимости в них. Типичный процесс редактирования файла включает в себя следующие моменты:
Для того, чтобы достичь таких же результатов эквивалентные операции в sed, состоящие из одной строчки, редактируют один и тот же файл, возможно, даже несколько раз, к тому же, без проверки безопасности.
Наличие определённых файлов может представлять опасность целостности системы, поэтому может потребоваться каким-либо образом гарантировать их отсутствие. Например, некоторые производители продают свои рабочие станции с символом + в файле /etc/hosts.equiv. Это значит, что любой пользователь в NIS домейне имеет свободный доступ к системе (без пароля). Поскольку это не лучший вариант, то, скорее всего, возникнет необходимость блокировать этот файл, переименовав, или просто удалить.
disable: /etc/hosts.equiv
Другие файлы представляют потенциальную опасность для системы, поскольку они настолько разрастаются, что занимают весь логический диск. Это особенно характерно для журналов регистрации, как, например, файлы System V /var/adm/wtmpx и `/var/lp/logs/lpsched'. Другие файлы, как /var/adm/messages сдвигаются системой, так что они не растут настолько, чтобы занять весь диск. Cfagent также может сдвигать такие файлы при задании
disable: Sunday:: /var/lp/logs/lpsched rotate=3
Таким образом, при запуске cfagent переименовал файл lpsched в файл lpsched.1. Также он переименовал lpsched.1 в lpsched.2 и так далее, пока число сдвигов не составило максимума в 3 файла. Файлы, которые уже имеют цифру 3 в своём названии, попадают в конец и навсегда удаляются. Такие действия не дают журналам регистрации слишком разрастаться. Если сохранять бэклоги (backlog) не требуется, тогда можно написать rotate-empty и cfagent будет просто опустошать журнал регистрации.
Каждый раз, когда cfagent блокирует файл (disable или links с оператором !) или сохраняет новый файл поверх старого (copy или editfiles), он всегда делает бэкап оригинала. Обычно блокированные файлы переименовываются путём добавления к их имени строки .cfdisabled, копии файлов с добавлением .cfsaved. Создание дублированных файлов в ходе действия copy можно отключить, установив переменную backup=false, но лучше использовать специальную директорию для блокированных и дублированных файлов, где будут храниться подобные файлы со всей системы. Такая директория называется хранилищем файлов (file repository) и определяется в части control программы, например: при объявлении copy, опция backup=timestamp может быть использована, чтобы разрешить множественные бэкапы. Это полезно при использовании cfengine для бэкапов дисков для пользователей, поскольку позволяет сосуществовать разным версиям.
control: repository = ( directory-name )
При определении такой переменной cfagent собирает все дублированные и блокированные файлы (за исключением сдвигаемых) в данной директории с использованием уникальных имён пути. В последствии, эти файлы можно открывать в хранилище и настроить чистку хранилища от старых фалов, которые больше не представляют интереса.
Цель cfagent прежде всего заключается в предоставлении системным администраторам простого интерфейса. Цель действий, встроенных в cfengine, - решать первоочередные, а не все подряд, задачи. Часто администраторам по-прежнему потребуется самим писать скрипты для выполнения более специфических заданий. Эти скрипты, тем не менее, также могут успешно запускаться через cfengine. Переменные и макросы, определённые в cfengine, могут использоваться и в скриптах, так что скрипты могут с максимальной пользовать использовать классовую структуруруктурус максимальной пользовайальной пользовай использовать классовую конструкцию.е специфичных задач.я, что занимаютщение о в. Также обращаем внимание, что поскольку дни недели в cfengine тоже являются классами, то вполне разумно запускать еженедельные скрипты с помощью механизмов cfengine (предполагая, что программа конфигурации выполняется ежедневно). Очевидное применение этому обновление баз данных, like fast-find database one day of the week (каждой базе данных сопоставить свой день недели, согласно которому её можно быстро найти), или запускать на дисках необходимое количество проверок.
shellcommands: myhost.Sunday:: "/usr/bin/find/updatedb"
Скрипты cfengine могут передаваться в качестве переменных c помощью обычной замены переменных.
control:
cfbin = ( /var/cfengine/bin ) backupdir = ( /iu/dax/backup ) shellcommands: "$(cfbin)/cfbackup -p -f $(backupdir) -s /iu/nexus/u1"
В случае, если необходимо написать некий особенно сложный скрипт, расширяющий возможности cfagent, может потребоваться полный доступ к уже определённым классам. Это можно сделать двумя способами:
CFALLCLASSES=class1:class2:...
Такая переменная содержит всегда обновлённый список созданных классов.
В двух предыдущих разделах был рассмотрен вопрос, как осуществлять циклический сдвиг старых лог файлов и как запускать команды shell. Если в системе хранится много старых лог файлов, то было бы хорошо иметь возможность сжимать их, чтобы они не занимали очень много места. Такая возможность реализовывается с помощью команды shell. В нижеприведённом примере происходит поиск фалов, соответствующих групповому символу shell. Имена типа file.1, file.2file.10 будут ему соответствовать и программа сжатия производит их сжатие. Результат выводится на экран(dumped) во избежание ложных сообщений.
shellcommands: "$(gnu)/gzip /var/log/*.[0-9] /var/log/*.[0-9][0-9] > /dev/null 2>&1"
Cfagent также сможет определить сдинутые файлы, если они были сжаты, с суффиксами .Z, gz, rbzили .rbz.
Списки контроля доступа представляют собой расширенные права доступа к файлу. Они позволяют предоставлять определённому списку пользователей возможность открывать и закрывать файл (не создавая при этом для них отдельную группу). Они также позволяют предоставлять такие возможности заданному списку групп. Ряд операционных систем, схожих с Unix, некоторое время имели списки контроля доступа, но в них не возникло большой необходимости.
Существует ряд объяснений таким проволочкам в прошлом. Инструменты для настройки ACL, как правило, интерактивны и не очень удобны в использовании. Из-за того, что определение списка пользователя повлечёт за собой слишком большое количество сообщений в листингах 1s -1, то ими, как правило, не пользуются. Но в связи с этим возникает опасность, что из-за скрытой информации возникнут ошибки, которые нельзя обнаружить, когда не те пользователи смогут открывать файлы. Также ACL различаются на каждой из покупаемых файловых систем и они не работают на подсистеме NFS. Несмотря на перечисленные минусы, использование ACL является весьма разумным. Здесь, в Колледже Осло, кажется, что пользователи постоянно спрашивают, как они могут разрешить открывать файл одному двум лицам, с которыми они работают. Они всегда использовали Novell/PC сети, которые стали применять технологии Apollo/NCS намного раньше. До этого Unix предлагал следующее решение их вопроса: необходимо попросить системного администратора создать для Вас отдельную группу. Затем решение заключалось в использовании chmod. После чего возник вопрос, а в чём же тогда заключается удобство использования Unix?
Решить вопрос такой недостаточной стандартизации стало задачей комитета по созданию проекта POSIX. Ряд производителей выпустили свою продукцию с использованием идей этого. Solaris 2.6 выпустил хороший вариант. Но не смотря на это, даже эти системы не предоставляли удобных инструментов работы с ACL. И никто не захочет возиться с таким вопросом, когда существует множество других, более стоящих, дел. Но несовместимость аргументов стала настоящей головной болью для производителей. Ряд организаций, которые разделяют данные в глобальном масштабе, выбрали более продвинутые решения для сетевых файловых систем, например, AFS и DFS. Такие файловые системы, как DCE и DFS широко используют файлы ACL и их работа не зависит от типа операционной системы. Но даже при этом DFS предлагает только интерактивные инструменты для анализа и установки прав доступа к файлам, что мало поможет системным администраторам, которые бы хотели, чтобы эту задачу решал скрипт, а не они.
Необходимость последнего весьма очевидна. Системы, использующие ACL для обеспечения безопасности, могут полностью развалиться, если в ACL поменять пару строк. В качестве примера можно привести операционные системы Apollo и Domain. Для того, чтобы развалить такие системы, нужно всего лишь изменить ряд ACL и забыть, какими они были раньше. Внезапно система начинает барахлить и ничего уже не работает. В случае, если нет бэкапа, единственный выход - удалить всё, что относилось к вопросу безопасности. В Unix вопросы надёжности решаются проще, когда речь идёт о файлах операционной системы, но ACL стало бы очень хорошим дополнением, обеспечивающим безопасность данных.
Базовая программа проверки файлов в cfagent выглядит примерно следующим образом:
# # Free format cfagent program # control: ActionSequence - ( files ) files: classes:: /directory/file mode=644 owner=mark,ds group=users,adm acl=zap action=fixplain # ... more below
Она просто проверяет права доступа и авторские права определённого файла. Режимный код файла, владелец и группа указаны напрямую. Новым здесь является объявление acl. На первый взгляд она может показаться очень простой, но на самом деле это необычайно мощный инструмент. Zap, конечно же, не является списком контроля доступа. За место этого для обращения к ACL cfagent использует систему алиасов. Это делается для того, чтобы множество самых разных определений ACL не повлияли на ясность команд файла. Алиас ACL задаётся в отдельной части программы, которая выглядит примерно так:
# ...contd acl: { zap method:append fstype:solaris user:rmz:rwx user:len:r }
Как видно, ACL является сложным объектом пакет информации определяет, какой пользователь, какими правами обладает. Поскольку ACL являются списками, алиасы также должны знать, следует ли добавлять элементы в существующие списки или заменить ими существующие списки. Кроме того, в связи с тем, что биты разрешений, общие параметры и интерфейс программ различаются для каждого типа файловых систем, необходимо сообщить cfagent тип используемой файловой системы.
Возможно связать несколько алиасов ACL с файлом. Когда cfagent связывает файлы с ACL, он читает существующий ACL и сравнивает его с новым. Изменения в файлах будут производиться только в том случае, если они не соответствуют спецификации в программе cfagent. Рассмотрим полный пример:
files: $(HOME)/myfile acl=acl_alias1 action=fixall acl: { acl_alias1 method:append fstype:solaris user:len:rwx }
ACL рассматриваются в Solaris с помощью команды getfacl. Предположим, что до запуска программы текстовый файл имел следующие права доступа:
user:*:rwx user:mark:rwx #effective:r-x group:*:r-x #effective:r-x mask:r-x other:r-x default_user:rw- default_group:r-- default_mask:-w- default_other:rwx
После выполнения cfagent, ACL станет:
user:*:rwx user:mark:rwx #effective:r-x user:len:rwx #effective:r-x group:*:r-x #effective:r-x mask:r-x other:r-x default_user:rw- default_group:r-- default_mask:-w- default_other:rwx
Допустим, требуется удалить опцию w для пользователя jacobs или убедиться, что у него её никогда не было.
{ acl_alias1 method:append fstype:solaris user:jacobs:-w }
Обратите внимание, что здесь используется метод конкатенации. Это значит, что какие бы права не предоставлялись на этот файл, пользователь jacobs (взломщик) никогда не получит разрешения на запись в него. Если бы ранее был использован метод overwrite, то можно было бы не описывать все прочие права доступа для каждого пользователя и просто добавить всё написанное выше. Если бы потребовалось полностью отстранить jacobs от пользования файлом, то есть запретить ему любые права доступа,это можно было бы сделать следующим образом:
user:jacobs:noaccess
Ключевое слово noaccess удаляет любые части определения. Обратите внимание, что это всегда совпадает с использованием rwx, поскольку некоторые файловые системы на подобие DFS имеют большее количество частей. Затем, если пользователь будет прощён, то ACL можно вернуть, записав
user:jacobs:default
В Solaris файлы унаследуют ACL по умолчанию из той папаки, в которой они находятся. Это можно изменить настройками umask для создания их собственной маски.
DFS ACL выглядит немного по-другому. Их можно проанализировать с помощью команды acl_edit или с помощью
dcecp -c acl show <filename>
Для того, чтобы внести изменения в DFS, необходимо войти в DCE, чтобы получить cookies для аутентификации. Пользователь cell_admin особенный пользовательский аккаунт для администрирования элементов DFS. Предположим, имеется файл со следующими DCE ACL:
mask_obj:r-x--- user_obj:rwxcid user:cell_admin:r--c-- #effective:r----- group_obj:r-x--d #effective:r-x--- other_obj:r-x---
Теперь требуется добавить права wx для пользователя cell_admin и добавить новые записи с правами rx для группы acct-admin и пользователя root. Это делается с помощью следующего ACL алиаса:
{ acl_alias2
method:append
fstype:dfs
user:/.../iu.hioslo.no/cell_admin:wx
group:/.../iu.hioslo.no/acct-admin:rx
user:/.../iu.hioslo.no/root:rx
user:*:-x
}
Здесь требуется локальное имя ячейки `/.../iu.hioslo.no'. Cfagent не может сам удалённо изменить ACL в других ячейках, но если программа cfengine охватывает все cell servers, тогда никаких ограничений не существует, поскольку по-прежнему можно сосредотачивать все ACL в одном месте. Выполнение и проверка происходят именно в распределённых местах. В этом и состоит одно из главных достоинств cfengine.
После выполнения cfagent с описанным выше кусочком программы ACL приобретает следующий вид
mask_obj:r-x--- user_obj:rwcid user:cell_admin:rwxc-- #effective:r-x--- user:root:r-x--- #effective:r-x--- group_obj:r-x--d #effective:r-x--- group:acct-admin:r-x--- other_bj:r-x---
Ради сохранения простоты здесь были использованы только стандартные обозначения Unix - rwx, но в DFS можно найти более сложные примеры. Такие как:
user:mark:+rwx,-cid
где разрешается чтение, запись и выполнение, но запрещается управление, вставка и удаление. В DFS файлы наследуют начальный объект ACL из их родительской директории, тогда как новые директории унаследуют начальный контейнер.
Объекты, которые в DFS обозначаются как user_obj, group_obj и т.д. ссылаются на владельца файла, то есть они эквивалентны соответствующим командам, действующим в зависимости от того, кто является владельцем рассматриваемого файла. Для того, чтобы упростить пользовательский интерфейс cfengine и сделать его более согласованным с формами в POSIX, суффиксы _objбыли выкинуты. Пользовательское поле * простое обозначение для владельца файла.
Проблема любой системы списков заключается в возможности создать такую последовательность, которая выполняет что-то, потом выполняет обратные этим действия и переделывает что-то другое, и всё это в одном несовместимом списке. Во избежание такого случайного взаимодействия, cfengine требует, чтобы каждый пользователь имел только одну ACE (access control entry запись контроля доступа), то есть, чтобы все права доступа для определённого пользователя содержались в одной записи.
Cfengine не является инструментом, это среда для управления конфигурацией и целостностью компьютеров. В данном пособии мы лишь в общих словах осветили возможности cfengine, но, для того чтобы полностью понять синтаксис рассмотренных примеров, необходимо обратиться к его документации.
Большим преимуществом cfengine переед многими другими схемами конфигурации является возможность иметь всё в одном файле (или наборе файлов). Глобальный файл является общим для всех компьютеров и, кроме того, в зависимости от желания он может быть как общим, так и специальным. Cfengine можно использовать в качестве фронт-энда для cron, а его дополнительные функции, чтобы привести компьютеры к правильному и желаемому состоянию.