Базы данныхИнтернетКомпьютерыОперационные системыПрограммированиеСетиСвязьРазное
Поиск по сайту:
Подпишись на рассылку:

Назад в раздел

Информационная безопасность систем управления базами данных

Информационная безопасность систем управления базами данных

Надежда Вьюкова, Владимир Галатенко
АО "Инфосистемы Джет"

1. Введение

Системы управления базами данных, в особенности реляционные СУБД, стали доминирующим инструментом хранения больших массивов информации. Сколько-нибудь развитые информационные приложения полагаются не на файловые структуры операционных систем, а на многопользовательские СУБД, выполненные в технологии клиент/сервер. В этой связи обеспечение информационной безопасности СУБД, и в первую очередь их серверных компонентов, приобретает решающее значение для безопасности организации в целом.
Для СУБД важны все три основных аспекта информационной безопасности - конфиденциальность, целостность и доступность [6]. Общая идея защиты баз данных состоит в следовании рекомендациям, сформулированным для класса безопасности C2 в "Критериях оценки надежных компьютерных систем". В принципе некоторые СУБД предлагают дополнения, характерные для класса B1, однако практическое применение подобных дополнений имеет смысл, только если все компоненты информационной структуры организации соответствуют категории безопасности B. Достичь этого непросто и с технической, и с финансовой точек зрения. Следует, кроме того, учитывать два обстоятельства. Во-первых, для подавляющего большинства коммерческих организаций класс безопасности C2 достаточен. Во-вторых, более защищенные версии отстают по содержательным возможностям от обычных "собратьев", так что поборники секретности по сути обречены на использование морально устаревших (хотя и тщательно проверенных) продуктов со всеми вытекающими последствиями в плане сопровождения.
Для иллюстрации излагаемых понятий и средств будут использоваться СУБД INGRES, Informix и Oracle.

2. Идентификация и проверка подлинности пользователей

Обычно в СУБД для идентификации и проверки подлинности пользователей применяются либо соответствующие механизмы операционной системы, либо SQL-оператор CONNECT. Например, в случае СУБД Oracle оператор CONNECT имеет следующий вид:

CONNECT пользователь[/пароль] [@база_данных];

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

3. Управление доступом

Для иллюстрации вопросов, связанных с управлением доступом, будет использоваться СУБД INGRES.

3.1. Основные понятия

Обычно в СУБД применяется произвольное управление доступом, когда владелец объекта передает права доступа к нему (чаще говорят - привилегии) по своему усмотрению. Привилегии могут передаваться субъектам (отдельным пользователям), группам, ролям или всем пользователям.
Группа - это именованная совокупность пользователей. Объединение субъектов в группы облегчает администрирование баз данных и, как правило, строится на основе формальной или фактической структуры организации. Каждый пользователь может входить в несколько групп. Когда пользователь тем или иным способом инициирует сеанс работы с базой данных, он может указать, от имени какой из своих групп он выступает. Кроме того, для пользователя обычно определяют подразумеваемую группу.
Роль - это еще один возможный именованный носитель привилегий. С ролью не ассоциируют перечень допустимых пользователей - вместо этого роли защищают паролями. В момент начала сеанса с базой данных можно специфицировать используемую роль (обычно с помощью флагов или эквивалентного механизма) и ее пароль, если таковой имеется.
Привилегии роли имеют приоритет над привилегиями пользователей и групп. Иными словами, пользователю как субъекту не обязательно иметь права доступа к объектам, обрабатываемым приложениям с определенной ролью.
Отметим, что в СУБД Oracle под ролью понимается набор привилегий. Такие роли служат средством структуризации привилегий и облегчают их модификацию.
Совокупность всех пользователей именуется как PUBLIC. Придание привилегий PUBLIC - удобный способ задать подразумеваемые права доступа.

3.2. Основные категории пользователей

Пользователей СУБД можно разбить на три категории:
администратор сервера баз данных. Он ведает установкой, конфигурированием сервера, регистрацией пользователей, групп, ролей и т.п. Администратор сервера имеет имя ingres. Прямо или косвенно он обладает всеми привилегиями, которые имеют или могут иметь другие пользователи. администраторы базы данных. К этой категории относится любой пользователь, создавший базу данных, и, следовательно, являющийся ее владельцем. Он может предоставлять другим пользователям доступ к базе и к содержащимся в ней объектам. Администратор базы отвечает за ее сохранение и восстановление. В принципе в организации может быть много администраторов баз данных. Чтобы пользователь мог создать базу и стать ее администратором, он должен получить (вероятно, от администратора сервера) привилегию creatdb. прочие (конечные) пользователи. Они оперируют данными, хранящимися в базах, в рамках выделенных им привилегий. В последующих разделах будет детально проанализирована система привилегий СУБД INGRES. Здесь мы отметим только, что администратор сервера баз данных, как самый привилегированный пользователь, нуждается в особой защите. Компрометация его пароля фактически означает компрометацию сервера и всех хранящихся на нем баз данных.
Поручать администрирование различных баз данных разным людям имеет смысл только тогда, когда эти базы независимы и по отношению к ним не придется проводить согласованную политику выделения привилегий или резервного копирования. В таком случае каждый из администраторов будет знать ровно столько, сколько необходимо.
Можно провести аналогию между пользователем ingres и администраторами баз данных с одной стороны, и суперпользователем операционной системы (root в случае ОС UNIX) и служебными пользователями (в ОС UNIX это могут быть bin, lp, uucp и т.д.) с другой стороны. Введение служебных пользователей позволяет администрировать функциональные подсистемы, не получая привилегий суперпользователя. Точно так же информацию, хранящуюся на сервере баз данных, можно разделить на отсеки, так что компрометация администратора одного отсека не означает обязательной компрометации другого.

3.3. Виды привилегий

Привилегии в СУБД можно подразделить на две категории: привилегии безопасности и привилегии доступа. Привилегии безопасности позволяют выполнять административные действия. Привилегии доступа, в соответствии с названием, определяют права доступа субъектов к определенным объектам.

3.3.1. Привилегии безопасности
Привилегии безопасности всегда выделяются конкретному пользователю (а не группе, роли или всем) во время его создания (оператором CREATE USER) или изменения характеристик (оператором ALTER USER). Таких привилегий пять:
security - право управлять безопасностью СУБД и отслеживать действия пользователей. Пользователь с этой привилегией может подключаться к любой базе данных, создавать, удалять и изменять характеристики пользователей, групп и ролей, передавать права на доступ к базам данным другим пользователям, управлять записью регистрационной информации, отслеживать запросы других пользователей и, наконец, запускать INGRES-команды от имени других пользователей. Привилегия security необходима администратору сервера баз данных, а также лицу, персонально отвечающему за информационную безопасность. Передача этой привилегии другим пользователям (например, администраторам баз данных) увеличивает число потенциально слабых мест в защите сервера баз данных. createdb - право на создание и удаление баз данных. Этой привилегией, помимо администратора сервера, должны обладать пользователи, которым отводится роль администраторов отдельных баз данных. operator - право на выполнение действий, которые традиционно относят к компетенции оператора. Имеются в виду запуск и остановка сервера, сохранение и восстановление информации. Помимо администраторов сервера и баз данных этой привилегией целесообразно наделить также администратора операционной системы. maintain_locations - право на управление расположением баз администраторы сервера баз данных и операционной системы. trace - право на изменение состояния флагов отладочной трассировки. Данная привилегия полезна администратору сервера баз данных и другим знающим пользователям при анализе сложных, непонятных ситуаций.

3.3.2. Привилегии доступа
Привилегии доступа выделяются пользователям, группам, ролям или всем посредством оператора GRANT и изымаются с помощью оператора REVOKE. Эти привилегии, как правило, присваивает владелец соответствующих объектов (он же - администратор базы данных) или обладатель привилегии security (обычно администратор сервера баз данных).
Прежде чем присваивать привилегии группам и ролям, их (группы и роли) необходимо создать с помощью операторов CREATE GROUP и CREATE ROLE.
Для изменения состава группы служит оператор ALTER GROUP.
Оператор DROP GROUP позволяет удалять группы, правда, только после того, как опустошен список членов группы.
Оператор ALTER ROLE служит для изменения паролей ролей, а DROP ROLE - для удаления ролей.
Напомним, что создавать и удалять именованные носители привилегий, а также изменять их характеристики может лишь пользователь с привилегией security. При совершении подобных действий необходимо иметь подключение к базе данных iidbdb, в которой хранятся сведения о субъектах и их привилегиях.
Привилегии доступа можно подразделить в соответствии с видами объектов, к которым они относятся. В СУБД INGRES таких видов пять:
таблицы и представления процедуры базы данных сервер баз данных события Присваивание привилегий доступа производится с помощью оператора GRANT. В самом общем виде оператор GRANT имеет следующий формат:

GRANT привилегии
ON объекты
TO кому;

Применительно к таблицам и представлениям можно управлять следующими правами доступа:
SELECT- право на выборку данных
INSERT- право на добавление данных
DELETE- право на удаление данных
UPDATE - право на обновление данных (можно указать определенные столбцы, разрешенные для обновления)
REFERENCES- право на использование внешних ключей, ссылающихся на данную таблицу (можно указать определенные столбцы)
По умолчанию пользователь не имеет никаких прав доступа к таблицам и представлениям - их необходимо передать с помощью операторов GRANT.
По отношению к процедуре можно предоставить право на выполнение. При этом не нужно заботиться о выделении прав доступа к объектам, обрабатываемым процедурой - их наличие не обязательно. Таким образом, процедуры баз данных являются удобным средством предоставления контролируемого доступа для выполнения строго определенных действий над данными.
Права доступа к базе данных как к единому целому может предоставлять ее администратор или пользователь с привилегией security. Эти "права" на самом деле устанавливают ряд ограничений на использование базы данных, то есть по сути являются запретительными. Имеется в виду ограничение на число операций ввода/вывода или число строк, возвращаемых одним запросом, ограничение права создания таблиц и процедур и т.п. По умолчанию пользователь не стесняется количественными лимитами и получает право на создание объектов в базе.
Отметим, что при создании базы данных указывается ее статус - общая или личная. Это влияет на подразумеваемые права доступа к базе. По умолчанию право на подключение к общей базе предоставляется всем. Право на подключение к личной базе нужно передавать явным образом. Право на подключение необходимо для выполнения всех прочих операций с базой и содержащимися в ней объектами.
Привилегии (которые в данном случае точнее было бы назвать ограничениями) QUERY_IO_LIMIT и QUERY_ROW_LIMIT проверяются на основании оценок, выданных оптимизатором запросов. Если оптимизатор предсказывает, что запрос превысит отведенный лимит числа операций ввода вывода или возвращаемых строк, он (запрос) отвергается. Наложение подобных количественных ограничений препятствует монополизации сервера одним клиентом и может использоваться как один из инструментов поддержания высокой готовности.
Обратим внимание на следующее любопытное обстоятельство. По умолчанию все пользователи имеют право создавать процедуры в базах данных. Если бы они при этом автоматически получали права на выполнение, то смогли бы осуществить по существу любую операцию с данными, поскольку выполнение процедуры не требует прав доступа к обрабатываемым объектам. К счастью, для передачи привилегии доступа к объектам, и в, частности, для предоставления права на выполнение процедуры, надо быть не только владельцем объекта, но и администратором базы данных. Мы видим, насколько осторожно нужно относиться к предоставлению привилегий выполнения по отношению к новым, непроверенным процедурам. В принципе достаточно одного "троянского коня", чтобы скомпрометировать всю базу данных. Процедуры являются столь же гибким, но и столь же опасным средством, что и UNIX-программы с битом переустановки действующего идентификатора пользователя.
Отметим, что запретительные привилегии в принципе можно наложить на администратора базы данных или администратора сервера, однако они не будут иметь силы. Тем самым злоумышленник лишен возможности ограничить права доступа администраторов. В частности, он не может создать личную "секретную" базу данных, к которой не будет иметь доступ пользователь ingres. Правда, у подобного положения есть и оборотная сторона - компрометация пароля администратор сервера предоставляет злоумышленнику неограниченные права доступа ко всем базам данных.
Права доступа к серверу распространяются на все базы данных, обслуживаемые данным серверам. Набор этих прав тот же, что и для отдельных баз данных.
Привилегии, явно определенные для отдельных баз, имеют приоритет над привилегиями сервера.
Механизм событий подробно рассмотрен в [1]. Здесь мы отметим лишь, что по отношению к событиям имеются две привилегии - RAISE и REGISTER. Первая позволяет возбуждать события, вторая - регистрироваться для их получения.
Оператор GRANT может содержать необязательную часть, принципиально важную для защиты СУБД. Имеется в виду конструкция

GRANT ...
...
WITH GRANT OPTION;

Подобный оператор GRANT передает не только указанные в нем привилегии, но и права на их дальнейшую передачу. Очевидно, что использование конструкции WITH GRANT OPTION ведет к децентрализации контроля над привилегиями и содержит потенциальную угрозу безопасности данных.
Для отмены привилегий, выданных ранее (как разрешительных, так и запретительных), служит оператор REVOKE.

3.3.3. Получение информации о привилегиях
Важно не только давать и отбирать привилегии, но и иметь информацию о том, какими правами доступа обладает каждый из субъектов. Подобные данные можно получить с помощью функции dbmsinfo, а также путем анализа содержимого таблиц в базе данных iidbdb.
Функция dbmsinfo возвращает права доступа к базе, относящиеся к текущему подключению. Можно узнать имена действующих группы и роли, значения количественных ограничений, наличие привилегий для создания таблиц и процедур и т.п.
Таблицы iiusergroup, iirole и iidbprivileges базы данных iidbdb содержат соответственно, список групп и их состав, перечень ролей вместе с зашифрованными паролями и сведения о привилегиях доступа к базам данных. Так, таблица iiusergroup состоит из трех столбцов:
groupid - имя группы, groupmem - имя члена группы, reserve - резервный столбец. Средствами SQL из этих таблиц можно извлечь необходимую информацию.

3.4. Использование представлений для управления доступом

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

CREATE VIEW empview AS
SELECT name, dept
FROM employee
WHERE dept = 'shoe';

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

GRANT SELECT
ON empview
TO PUBLIC;

Субъекты, осуществляющие доступ к представлению empview, могут пытаться запросить сведения об отделах, отличных от shoe, например:

SELECT *
FROM empview
WHERE dept = 'toy';

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

3.5. Иерархия прав доступа

Оператор GRANT и другие средства управления доступом СУБД позволяют реализовать следующие виды ограничения доступа:
операционные ограничения (за счет прав доступа SELECT, INSERT, UPDATE, DELETE, применимых ко всем или только некоторым столбцам таблицы); ограничения по значениям (за счет механизма представлений); ограничения на ресурсы (за счет привилегий доступа к базам данных). При обработке запроса СУБД сначала проверяет права доступа к объектам. Если операционные ограничения оказываются нарушенными, запрос отвергается с выдачей соответствующей диагностики. Нарушение ограничений на значения влияет только на количество результирующих строк; никакой диагностики при этом не выдается (см. предыдущий пункт). Наконец, после учета двух предыдущих ограничений, запрос поступает на обработку оптимизатору. Если тот обнаружит превышение ограничений на ресурсы, запрос будет отвергнут с выдачей соответствующей диагностики.
На иерархию привилегий можно посмотреть и с другой точки зрения. Каждый пользователь, помимо, собственных, имеет привилегии PUBLIC. Кроме этого, он может входить в различные группы и запускать приложения с определенными ролями. Как соотносятся между собой права, предоставленные различным именованным носителям привилегий?
Иерархия авторизации выглядит для СУБД INGRES следующим образом:
роль (высший приоритет) пользователь группа PUBLIC (низший приоритет) Для каждого объекта, к которому осуществляется доступ, INGRES пытается отыскать в иерархии привилегию, относящуюся к запрашиваемому виду доступа (SELECT, EXECUTE и т.п.). Например, при попытке доступа к таблице с целью обновления, INGRES проверяет привилегии роли, пользователя, группы и всех пользователей. Если хотя бы на одном уровне иерархии привилегия UPDATE имеется, запрос передается для дальнейшей обработки. В противном случае используется подразумеваемое право доступа, которое предписывает отвергнуть запрос.
Рассмотрим подробнее трактовку ограничений на ресурсы. Пусть, например, на всех четырех уровнях иерархии специфицированы свои ограничения на число результирующих строк запроса (привилегия QUERY_ROW_LIMIT):
роль1700
пользователь1500
группа2000
PUBLIC1000
Если пользователь в момент начала сеанса работы с СУБД задал и роль, и группу, будет использовано ограничение, накладываемое ролью (1700). Если бы привилегия QUERY_ROW_LIMIT для роли отсутствовала, или пользователь не задал роль в начале сеанса работы, пользователь смог бы получать результаты не более чем из 1500 строк и т.п. Если бы привилегия QUERY_ROW_LIMIT вообще не была специфицирована ни на одном уровне иерархии, СУБД воспользовалась бы подразумеваемым значением, которое в данном случае означает отсутствие ограничений на число результирующих строк.
Обычно используемая роль и группа задаются, соответственно, как аргументы опций -R и -G в командной строке запуска приложения. Пример:

QBF -Gaccounting company_db

Если опция -G отсутствует, применяется подразумеваемая группа пользователя, если таковая имеется.
Наконец, если в командной строке sql задана опция

-uпользователь

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

3.7. Метки безопасности и принудительный контроль доступа

Выше были описаны средства произвольного управления доступом, характерные для уровня безопасности C. Как уже указывалось, они в принципе достаточны для подавляющего большинства коммерческих приложений. Тем не менее, они не решают одной весьма важной задачи - задачи слежения за передачей информации. Средства произвольного управления доступом не могут помешать авторизованному пользователю законным образом получить секретную информацию и затем сделать ее доступной для других, неавторизованных пользователей. Нетрудно понять, почему это так. При произвольном управлении доступом привилегии существуют отдельно от данных (в случае реляционных СУБД - отдельно от строк реляционных таблиц). В результате данные оказываются "обезличенными", и ничто не мешает передать их кому угодно даже средствами самой СУБД.
В "Критериях оценки надежных компьютерных систем", применительно к системам уровня безопасности B, описан механизм меток безопасности, реализованный в версии INGRES/Enhanced Security (INGRES с повышенной безопасностью). Применять эту версию на практике имеет смысл только в сочетании с операционной системой и другими программными компонентами того же уровня безопасности. Тем не менее, рассмотрение реализации меточной безопасности в СУБД INGRES интересно с познавательной точки зрения, а сам подход, основанный на разделении данных по уровням секретности и категориям доступа, может оказаться полезным при проектировании системы привилегий многочисленных пользователей по отношению к большим массивам данных.
В СУБД INGRES/Enhanced Security к каждой реляционной таблице неявно добавляется столбец, содержащий метки безопасности строк таблицы. Метка безопасности состоит из трех компонентов:
Уровень секретности. Смысл этого компонента зависит от приложения. В частности, возможен традиционный спектр уровней от "совершенно секретно" до "несекретно". Категории. Понятие категории позволяет разделить данные на "отсеки" и тем самым повысить надежность системы безопасности. В коммерческих приложениях категориями могут служить "финансы", "кадры", "материальные ценности" и т.п. Ниже назначение категорий разъясняется более подробно. Области. Является дополнительным средством деления информации на отсеки. На практике компонент "область" может действительно иметь географический смысл, обозначая, например, страну, к которой относятся данные. Каждый пользователь СУБД INGRES/Enhanced Security характеризуется степенью благонадежности, которая также определяется меткой безопасности, присвоенной данному пользователю. Пользователь может получить доступ к данным, если степень его благонадежности удовлетворяет требованиям соответствующей метки безопасности. Более точно:
уровень секретности пользователя должен быть не ниже уровня секретности данных; набор категорий, заданных в метке безопасности данных, должен целиком содержаться в метке безопасности пользователя; набор областей, заданных в метке безопасности пользователя, должен целиком содержаться в метке безопасности данных. Рассмотрим пример. Пусть данные имеют уровень секретности "конфиденциально", принадлежат категории "финансы" и относятся к областям "Россия" и "СНГ". Далее, пусть степень благонадежности пользователя характеризуется меткой безопасности с уровнем секретности "совершенно секретно", категориями "финансы" и "кадры", а также областью "Россия". Такой пользователь получит доступ к данным. Если бы, однако, в метке пользователя была указана только категории "кадры", в доступе к данным ему было бы отказано, несмотря на его "совершенно секретный" уровень.
Когда пользователь производит выборку данных из таблицы, он получает только те строки, меткам безопасности которых удовлетворяет степень его благонадежности. Для совместимости с обычными версиями СУБД, столбец с метками безопасности не включается в результирующую информацию.
Отметим, что механизм меток безопасности не отменяет, а дополняет произвольное управление доступом. Пользователи по-прежнему могут оперировать с таблицами только в рамках своих привилегий, но даже при наличии привилегии SELECT им доступна, вообще говоря, только часть данных.
При добавлении или изменении строк они, как правило, наследуют метки безопасности пользователя, инициировавшего операцию. Таким образом, даже если авторизованный пользователь перепишет секретную информацию в общедоступную таблицу, менее благонадежные пользователи не смогут ее прочитать.
Специальная привилегия, DOWNGRADE, позволяет изменять метки безопасности, ассоциированные с данными. Подобная возможность необходима, например, для коррекции меток, по тем или иным причинам оказавшихся неправильными.
Представляется естественным, что СУБД INGRES/Enhanced Security допускает не только скрытое, но и явное включение меток безопасности в реляционные таблицы. Появился новый тип данных, security label, поддерживающий соответствующие операции сравнения.
INGRES/Enhanced Security - первая СУБД, получившая сертификат, эквивалентный аттестации на класс безопасности B1. Вероятно, метки безопасности постепенно войдут в стандартный репертуар систем управления базами данных.

4. Поддержание целостности данных в СУБД

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

4.1. Ограничения

Ограничения могут относиться к таблицам или отдельным столбцам. Ограничения на столбцы задаются при создании таблицы, в операторах CREATE TABLE
Табличные ограничения относятся к группе столбцов и могут задаваться как при создании таблицы, так и позже, посредством оператора ALTER TABLE.
Следующий пример содержит именованное ограничение, связывающее значения в двух столбцах:

CREATE TABLE dept (
dname char(10),
budget money,
expenses money,
CONSTRAINT check_amount CHECK (budget > 0 and expenses


  • Главная
  • Новости
  • Новинки
  • Скрипты
  • Форум
  • Ссылки
  • О сайте




  • Emanual.ru – это сайт, посвящённый всем значимым событиям в IT-индустрии: новейшие разработки, уникальные методы и горячие новости! Тонны информации, полезной как для обычных пользователей, так и для самых продвинутых программистов! Интересные обсуждения на актуальные темы и огромная аудитория, которая может быть интересна широкому кругу рекламодателей. У нас вы узнаете всё о компьютерах, базах данных, операционных системах, сетях, инфраструктурах, связях и программированию на популярных языках!
     Copyright © 2001-2024
    Реклама на сайте