The OpenNET Project / Index page

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

Каталог документации / Раздел "Операционные системы" / Оглавление документа

7. Cfengine и вопросы безопасности

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

7.1. Что такое безопасность?

Безопасность компьютера, в первую очередь, подразумевает *физическую безопасность* - если возможно залезть непосредственно в компьютер, то тогда можно просто развинтить его на части. Но если допустить, что компьютер в физическом смысле в безопасности, то тогда можно начать рассматривать вопросы о безопасности программного обеспечения, которые гораздо сложнее. Главным в безопасности программного обеспечения является контроль доступа и надёжность самого программного обеспечения. Ни один инструмент не может сделать систему безопасной. Все крупные ошибки были сделаны из-за уверенности в том, что один продукт (например, firewall) решит все вопросы безопасности. Например, несколько лет назад взломщик с помощью своего Web-броузера удалил все пользовательские директории с коммутируемого логин-сервера, принадлежащего крупной норвежской телекоммуникационной компании. Это стало возможным даже несмотря на наличие firewall, поскольку web-сервер на взламываемом компьютере был неправильно сконфигурирован. Подводя итог, не существует такого понятия, как безопасная операционная система, firewall или что-либо ещё. В данном вопросе требуется поддерживать постоянную бдительность и приспосабливаемость.

Для многих безопасность воспринимается, как синоним к конфиденциальности сети или проникновениию в сеть. Конфиденциальность это один аспект безопасности, но не сеть является главным врагом. Многие нарушения безопасности происходят изнутри. Между опасностью удалённого доступа из сети и прямого доступа из консоли не существует большой разницы: конфиденциальность тесно связана с контролем доступа, вне зависимости от того, где может находиться потенциальный взломщик. Сосредоточивая всё внимание на заботе о сетевых соединениях, мы забываем о возможной угрозе со стороны внутренних пользователей (например, вахтёр эксперт в компьютерах с доступом к сети или непослушный сын директора, который остался поиграть в мамином офисе, или, совсем невероятное, разозлённый сотрудник, которому кажется, что его труд не ценят). Безопасность программного обеспечения очень обширный вопрос в связи с комплексностью современных компьютерных систем. Он только усложняется возможным соединением с Internet, которое даёт возможность миллионам людей взламывать сетевые системы. Это говорит о том, что безопасность требует жёсткого управления контролем доступа на каждом компьютере отдельно, а не только особенными элементами, такими как firewall.

Эта статья не является простым руководством по безопасности. Скорее, её целью является рассказать, как можно использовать cfengine, чтобы помочь автоматизировать уровень сохранности для всех компьютеров сети. Cfengine инструмент конфигурации сети с двумя аспектами. Это язык для создания экспертной системы. Экспертная система описывает то, как компьютеры и сеть должны выглядеть и работать. Также cfengine является software-роботом, который сравнивает описанную модель с тем, что есть на самом деле, а затем принимается исправлять все отклонения от установок. Во многих случаях он работает как иммунная система, нейтрализуя и восстанавливая повреждённые части. В отличие от пакетов для системного администрирования, содержащих скрипты shell, cfengine является программой на C, что значит его легковесность для ресурсов системы. Кроме того, он работает по принципу конвергенции (сходимости). Это значит, что каждый раз при запуске cfengine система будет всё больше и больше походить на описанную изначально модель, пока, наконец, она не станет абсолютно такой же. Тогда cfengine переходит в состояние покоя, в точности как иммунная система. И как сказал один пользователь: компьютер никогда не становится хуже. Это, естественно, предполагает, что описанная модель и есть желаемый результат. С использованием cfangine построение модели становится синонимичным формулированию и формализации системной политики.

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

7.2 Небольшое предостережение

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

7.3 Автоматизация

Даже для самой маленькой местной сети желательно создать схему автоматизации процессов конфигурации и поддержки компьютеров, поскольку система имеет свойство достаточно быстро расширяться с одного компьютера до большого количества. Именно поэтому важно разработать масштабируемую модель. Масштабируемость является довольно веской причиной для использования cfengine: один ли компьютер в сети или сотня - не играет никакого значения. Управление cfengine осуществляется из центральной точки, но его действия полностью и равномерно распространяется на всю сеть. Каждый компьютер отвечает за то, чтобы получить копию сетевой модели из надёжного источника, а затем сконфигурировать себя самостоятельно без какого-либо стороннего вмешательства. В отличие от ряда других моделей, cfengine не нужно полагаться на сетевое соединение или удалённые объектные модели.

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

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

Как и иммунная система, cfengine будет хорошо функционировать даже в условиях частичного соединения, поскольку он заставляет каждый компьютер самостоятельно отвечать за своё состояние. Он не доверяет сетевым соединениям для удалённых вызовов или запросам в стиле COBRA, как, например, Tivoli. Всё что ему требуется подлинная копия документа с конфигурацией системы, хранящемся локально на каждом компьютере. Если она имеется, то ни один из разъединённых компьютеров не останется незащищённым. В худшем случае такой компьютер просто не получит вовремя новую версию системной конфигурации.

7.4. Доверие

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

Например, любой NFS сервер пользовательских домашних директорий доверяет привилегированному пользователю на компьютерах, монтирующих данные директории. Ряд неприятностей предотвращаются за счёт передачи привилегий суперпользователя на нулевого пользователя (user nobody) удалённой системы, но это не является аспектом безопасности, а всего лишь удобство. Привилегированный пользователь всегда может использовать su для того, чтобы стать любым пользователем в его файле с паролем и осуществлять доступ \ изменять любые данные внутри таких файловых систем. Файлы .rlogin и hosts.equiv на машинах Unix предоставляют привилегии главного (или любого другого) пользователя другим компьютерам без аутентификации.

Сбор программного обеспечения с удалённых серверов должен осуществляться с компьютеров, которым гарантированно можно доверять, особенно если это файлы, которые могут предоставить особые привилегии доступа к системе. Даже контрольные суммы не окажутся эффективными, если  им нельзя доверять. Например, невероятно глупым было бы копировать бинарную программу, как, например, /bin/ps с компьютера, о котором ничего неизвестно. Эта программа запускается с привилегиями главного (root) пользователя. Если кто-нибудь заменил бы эту версию ps Троянским конём, то безопасность системы встала бы под угрозу. Многие пользователи доверяют анонимным FTP серверам, с которых они бесплатно скачивают программное обеспечение. В ходе любого удалённого копирования устанавливаются полностью доверительные отношения. В первую очередь, это вера в честность компьютера, с которого закачиваются файлы. Во-вторых, если говорить о контроле доступа, это вера в то, что они имеют такую же базу данных с именами пользователей. Привилегированный пользователь на скачивающем компьютере имеет такие же права на чтение файлов, что и привилегированный пользователь на сервере. Это же относится и к любому совпадающему имени пользователя.

7.5. Почему cfengine можно доверять?

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

Cfengine предполагает, что его входной файл полностью надёжен. За исключением этого входного файла, ни одна часть cfengine не принимает и не использует никакой информации о конфигурации от внешних источников. Максимум, что можно сделать через достоверное сетевое соединение попросить cfengine выполнить (или не выполнять) определённые части его модели. Таким образом, в худшем случае взломщик может заставить программу правильно сконфигурировать его компьютер. Говоря коротко, никто за исключением корня localhost может заставить программу выполнять какие-либо действия (если только доступ к корню системы уже не был взломан каким-то другим путём). Это значит, что существует только одна возможность взлома. Входной файл даже не должен быть приватным, поскольку он является аутентичным. Никто, кроме главного пользователя, не может управлять работой cfengine.

Однако существует один подвох. Cfengine может быть использован для удалённой пересылки файлов. В ходе удалённой передачи также необходимо доверять надёжности получаемых данных, как и в случае удалённого копирования. Несмотря на то, что cfengine усиленно пытается установить подлинность компьютера, как только однажды она была установлена, он уже не сможет проверять точность неизвестных получаемых данных. Кроме того, как и в случае со всеми удалёнными передачами файлов, cfengine может быть обманут DNS "спуфингом" при соединении с платным хостом. Поэтому, если Вы не доверяете своему DNS сервису, используйте IP адреса, а не имена компьютеров. Коротко говоря, такие проблемы часто возникают при удалённом копировании и никак не связаны с работой cfengine. Кроме того, это никак не связано с шифрованием, как иногда думают пользователи: шифрование соединения не влияет вышеупомянутые доверительные отношения, они улучшают систему защиты передаваемых данных, но никак не их точность или достоверность.

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

7.6. Конфигурация

Безопасность начинается с правильной конфигурации компьютеров. Даже при наличии 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. Они выбраны не для того, чтобы выделить их как наиболее или наименее надёжные, а исключительно из соображений их распространённости и определённости.

7.7. Блокирование и замена программного обеспечения

Одним из самых простых заданий, которые постоянно приходится выполнять, является блокировка опасных программ при обнаружении ошибок. Предупреждения от 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"
}

7.8 Управление процессами

В управлении процессами нас, как правило, интересуют три вещи: 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

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

7.9. Управление файлами

Практически все существующие программы безопасности созданы для того, чтобы отслеживать целостность файлов. 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.

7.10 Лог setuid

Cfengine всегда с особой осторожностью относиться к файлам, которые являются setuid или setgid суперпользователями (setuid setgid root). Он не станет активно осуществлять их поиск без специального запроса, но каждый раз при запуске cfagent для проверки файла или директории со свойствами файлов он обязательно отметит найденные программы setuid. Это будет записано в файле cfengine.host.log, находящийся в /var/cfengine или /var/log/cfengine. Каждый раз при обнаружении программ setuid, будет выдано предупреждение, но только суперпользователю. Для того чтобы иметь полный список, необходимо очистить журнал регистрации, тогда cfengine будет считать все найденные программы setuid новыми. Журнал регистрации не доступен для чтения обычным пользователям.

7.11. Подозрительные имена файлов

Каждый раз, когда 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

 

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

7.12 Контрольные суммы и функциональность Tripwire

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.

7.13 Расширения файлов

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

FileExtensions = ( c o gif jpg html )

7.14. NonAlphaNumFiles

Если включить данную опцию, то cfagent будет распознавать и блокировать файлы, имена которых не являются буквенно-цифровыми, то есть которые могли быть случайно или специально замаскированы. Такие файлы помечаются суффиксом .cf-nonalpha и считаются видимыми.

NonAlphaNumFiles = ( on )

Эти файлы можно почистить (удалить) или блокировать, осуществляя поиск на соответствие с образцом. Обратите внимание, что буквенно-цифровой обозначает из кода ascii менее 32 и более 126.

7.15 Сборка мусора как мера безопасности

Можно беспокоится о том, что взломщики выведут из строя системы и сделают её полностью непригодной для пользования, тогда как довольно много операционных систем спрограммированы так, что могут сделать это самостоятельно. Существует довольно мало систем, которые могут справиться с переполненным системным диском, и, по факту, большинство журналов регистрации продолжают заполнять диск, никогда не проверяя, есть ли на нём ещё место. Коротко говоря, они губят сами себя мнимыми 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). Надеемся, что этот недостаток вскоре будет исправлен.

7.16 Пример анонимного FTP

При конфигурации таких сервисов, как анонимные 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):"
}

7.17. Безопасность WWW

Безопасность вэб вряд ли является чем-то парадоксальным. С одной стороны, система создаётся для распространения файлов кому угодно без запроса пароля. С другой стороны, хотелось бы установить некоторые ограничения на то, кто и какую информацию может получать, и кто и какой может обмениваться. При желании обеспечить конфиденциальность в вэб необходимо исключить возможность запуска 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

7.18. Разные аспекты безопасности самого cfengine

control:
SecureInput = ( on )

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

7.19 Конфиденциальность (шифрование)

Шифрование (конфиденциальность) не часто оказываться серьёзной задачей системного администрирования. За исключением раздачи паролей и секретных ключей, не существует причины поддерживать какой-либо уровень конфиденциальности при передаче системных файлов (бинарных, например). Использовать инструмент типа 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

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

7.20. Гонки за доверием и ключами

Доверие центральное понятие в безопасности любой системы. Открытые и частные ключи помогают доверять другим компьютерам, но только после того как подлинные и правильные общие ключи были безопасно переданы всем, кому необходимо. До того как это произошло, необходимо быть уверенным в подлинности удалённых компьютеров. В рамках политики безопасности 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 такого предположения не делает.

7.21. Адаптивные блокировщики

Cfengine воспринимает все свои операции как блокированные транзакции. Блокировка предотвращает возникновение конфликтов между сосуществующими процессами и он также накладывает определённые ограничения на длительность выполнения программы. Тот факт, что операции заблокированы значит, что несколько программ cfengine могут сосуществовать без каких-либо трудностей. За то, как операции могут устанавливать блокировщики, отвечают два блокирующих параметра. Параметр IfElapsed сообщает операциям, что они могут быть исполнены только по прошествии определённого количества времени с момента последнего выполнения этого действия, что обеспечивает защиту от спама. Параметр ExpireAfter сообщает cfengine максимальную временную продолжительность действия, что обеспечивает защиту от зависших подчинённых процессов.

7.22. Спуфинг

Под спуфингом понимается попытка замаскироваться под другой компьютер во время осуществления обмена по сети. Программа cfservd, которую можно использовать для передачи файлов или удалённого запуска cfengine, пытается выявить такие попытки с помощью создания двойных обратных тупиков на сервисе имён. Доверенный сервер должен подтвердить, что сокет адрес и имя компьютера на самом деле являются теми, которыми они себя объявляют.

7.23. Состояние гонок при копировании файлов

При копировании файлов с источника существует вероятность, что в ходе работы возникнут сбои и взамен останется искажённый файл. Например, в течение копирования файла может переполниться диск, что может повлечь за собой проблемы. Cfengine справляется с этим за счёт копирования в новый файл получающей файловой системы (prefix.cfnew), а затем переименовывает его обратно только в случае успешной передачи. Это гарантирует наличие места в файловой системе и отсутствие проблем с системным соединением или диском в процессе копирования.

7.24. size = в операции copy

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

7.25 useshell = и owner = в командах shell

Существует определённая опасность в запуске скриптов из программ, которые работают с привилегиями суперпользователя. Как правило, как правило, команды shell запускаются исполнением с помощью команды /bin/sh-c. Главная проблема заключается в том, что она оставляет возможность для различных атак. Одним из примеров является обман, в результате которого shell  начинает исполнять другие программы, который становится возможным за счёт использования IFS переменной, чтобы толковать / как разделитель. Можно попросить cfengine запускать программы непосредственно, не прибегая к посредничеству shell, если присвоить переменной useshell значение ложь. Недостаток заключается в отсутствии возможность использовать директивы shell, такие как | или > в пользовательских командах. Директива owner=uid исполняет команды shell как для особенного пользователя, позволяя осуществлять безрпасный запуск скриптов без привилегий корня.

 

7.26. Firewalls

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




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

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