Приложения в операторской области требуют особых мер предосторожности, поэтому контроль доступа должен быть возможным на уровне процессов. В статье показывается, как при помощи опций IP в распределенном модуле безопасности (Distributed Security Module, DSM) можно рассылать информацию о безопасности в распределенной среде.

Проект распределенной инфраструктуры безопасности (Distributed Security Infrastructure, DSI) с открытыми исходными кодами лаборатории Open Systems Labs был создан в Ericsson Research с целью разработки инфраструктуры для обеспечения безопасности кластеров для телекоммуникационных приложений реального времени. Работа последних не должна прерываться ни при каких обстоятельствах, включая любые ошибки аппаратного и программного обеспечения. Кроме того, они должны позволить операторам устанавливать аппаратное и программное обеспечение (ядра и приложений) без заведомых простоев и нанесения ущерба оказываемым услугам.

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

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

РАСПРЕДЕЛЕННЫЙ МОДУЛЬ БЕЗОПАСНОСТИ

Распределенный модуль безопасности (Distributed Security Mobile, DSM) — центральный компонент DSI, обеспечивающий реализацию обязательного контроля доступа в пределах кластера Linux. Кроме того, DSM отвечает также за маркировку сообщений IP атрибутами безопасности отправляющего процесса и узла по всем узлам кластера.

DSM реализован в виде модуля при помощи ловушки (hook) модуля безопасности Linux (Linux Security Module, LSM). Разработка началась вместе с ядром 2.4.17 и соответствующими заплатами LSM. Реализация базировалась на стандартах CIPSO и FIPS-188, где определяются изменения заголовка IP.

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

Рисунок 1. Маршрут сетевого пакета через ядро.

Обработка пакетов необходима как для входящих, так и для исходящих пакетов (см. Рисунок 1). Исходящие пакеты обрабатываются следующим образом: приложение подготавливает данные, подлежащие отправке в сеть, после чего вызывает ядро, отправляющее пакет. Пакет в форме структуры sk_buff проходит через функции фильтрации и маршрутизации в пределах ядра и передается сетевому драйверу, который отправляет пакет сетевой карте (прямой доступ к памяти — Direct Memory Access, DMA).

Входящие сетевые пакеты принимаются сетевой картой с их собственным или широковещательным адресом. Карта передает пакеты сетевому накопителю и вызывает прерывание. Сервисная процедура прерываний инициируется аппаратным прерыванием, будучи частью драйвера сетевой карты внутри ядра. Она выделяет sk_buff и переносит данные из памяти карты в этот буфер (DMA). После чего пакет ставится в очередь к процессору для обработки на более высоком уровне. Обработка осуществляется позже, когда активируются прерывания. Наконец пакеты проходят через функции фильтрации и маршрутизации и передаются на уровень приложений.

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

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

  • NF_ACCEPT - программа разрешает пакету пройти через сетевой стек;
  • NF_DROP - пакет не допускается к обработке;
  • NF_STOLEN - пакет вызывает подозрения и не допускается к обработке;
  • NF_QUEUE - сетевой код ставит пакет в очередь для обработки в пользовательском пространстве;
  • NF_REPEAT - ловушка вызывается еще раз.

Пакет IP может содержать различный объем дополнительной информации (максимум 40 байт), вслед за стандартным заголовком длиной 20 байт. Эти расширения называются опциями IP, причем некоторые из них содержат информацию о безопасности. Internet Protocol предусматривает две опции безопасности. Первая, базовая DoD, — (DoD Basic Security Option, BSO, тип 130), — предусматривает маркировку дейтаграмм IP в соответствии с классификациями безопасности. Она предлагает 16 классификаций и множество ограничений по обработке. Вторая — расширенная опция безопасности DoD (Extended Security Option, ESO, тип 133) — служит для работы с категориями или областями безопасности.

Умеренное количество форматных кодов ESO не в состоянии поддерживать все возможные приложения коммерческой опции безопасности. BSO и ESO ориентированы лишь на министерство обороны Соединенных Штатов, в то время как коммерческая опция безопасности IP (Commercial IP Security Option, CIPSO) рассчитывает на большее число правил безопасности.

Опции IP для маркировки пакетов в реализации DSI базируются на стандарте FIPS 188 и проекте CIPSO. Для нужд этих стандартов заголовок IP был изменен так, чтобы только пользователь мог добавлять в него информацию о безопасности и отправлять ее через сеть.

ОПЦИИ IP В DSM

Идентификаторы безопасности (Security ID, SID) и идентификаторы узлов безопасности (Security Node ID, NID) должны переводиться в опции IP. DSM изменяет каждый пакет IP, предоставляя информацию о безопасности как опцию IP. На Рисунке 2 изображен формат модифицированного заголовка IP. Возможны следующие опции заголовка:

Рисунок 2. Опции безопасности в заголовке IP.
  • CIPSO — октет со значением 134;
  • длина — октет, общая длина опции, включая поля типа и длины. На данный момент действует ограничение длины заголовка IP в 40 октетов;
  • идентификатор домена интерпретации (Domain of Interpretation, DOI) — беззнаковое целое число длиной 32 бит. Значение «0» зарезервировано и не может появляться в опции CIPSO в качестве идентификатора DOI. При реализации следует исходить из того, что поле идентификатора DOI не ориентировано на определенную границу в байтах;
  • поле CIPSO DOI или Security Tag Set Name согласно FIPS 188 — шестнадцатеричное значение 10001000;
  • свободная форма — октет указывает на то, что следующие поля являются новыми, для которых нет стандарта. Значение равно 7;
  • длина — октет задает общую длину всех тегов;
  • теги (SID, NID) — CIPSO использует наборы тегов, где содержится относящаяся к данным пакета IP информация о безопасности. Каждый тег начинается с идентификатора типа, затем следует длина тега и собственно информация о безопасности, которая должна передаваться далее;
  • тег SID — идентификатор тега — один октет (значение 3), длина тега — один октет (значение 6), данные тега — значение SID длиной 32 бит;
  • тег NID — идентификатор тега — один октет (значение 6), длина тега — один октет (значение 6), данные тега — значение NID длиной 32 бит;
  • применяемая в CIPSO опция IP — эти поля в стандарте не определены;
  • DOI и FIPS 188 (свободная форма) — следующие поля являются новыми, т. е. неопределенными полями.

В представленной реализации DSM снабжена ловушками безопасности LSM для добавления в сообщения IP меток безопасности. Принцип действия можно показать на примере приложения, передающего пакеты в сеть через сокет. Приложение пользуется некоторыми обращениями к библиотекам. В определенный момент системный вызов передает сообщение ядру Linux. Точку входа для реализации сокета ядра представляет функция sys_socketcall(), находящаяся в net/socket.c. В ряду запросов выполняется функция sock_sendmsg() в net/socket.c (см. Листинг 1).

Прежде всего функция выполняет ловушку безопасности (security_ops->socket_ops->sendmsg(...)), которая входит в ловушку сокета DSM, модифицирующую пакет IP (см. Листинг 2). Функция dsi_options_fill помещает информацию о безопасности в буфер. Позже прочие функции добавляют эту информацию о безопасности сообщению IP в качестве опций. Пользователь получает SID из идентификатора безопасности сокета. NID имеет силу для всего узла, поэтому нет необходимости передавать его как параметр функции.

Затем модифицированный пакет с информацией о безопасности передается в ядро для обычной обработки и отправляется через сеть. На стороне получателя входящие сообщения сохраняются в структуры sk_buff и дополнительно обрабатываются при помощи ряда функций и ловушек. Одной из таких функций является ip-options-compile (см. Листинг 3) в net/ipv4/ip_options.c, где и обрабатываются опции.

В случае CIPSO вызывается ловушка безопасности decode_options, заменяемая в DSM на dsi_decode_options. Она считывает и сохраняет параметры безопасности (SID, NID) входящих пакетов в структуре безопасности, ассоциированной с sk_buff. Промежуточные хранилища sk_buff с информацией о безопасности добавляются в приемную очередь сокета, где они ждут своего прочтения получающим приложением. Для этой цели, как и для отправляемых пакетов, приложение выдает системный запрос sys_socketcall(). Если у сокета нет права принимать пакеты с определенным идентификатором безопасности, то пакет получает отказ. Листинг 4 показывает функцию ядра в include/net/sock.h. После вызова ловушки безопасности sock_rcv_skb при загрузке DSM он заменяется на функцию DSM dsi_ sock_rcv_skb, которая производит проверку безопасности.

Сравнительные тесты призваны были проверить, в какой мере добавление опций в заголовок IP влияет на общую производительность. Так, одно из испытаний предусматривало обмен пакетом UDP между узлами кластера и измерение падения производительности вследствие модификации безопасности пакета на отсылающей стороне, включая отбор безопасности пакета у получателя. Появление дополнительных функций обеспечения безопасности привело к тому, что средний рост объема служебных сигналов составил 30%. Большую часть из них (около 25%) вызвало изменение пакета IP на базе опции безопасности IP. Оставшиеся возникли вследствие инфраструктуры ловушек безопасности в ядре Linux, таких, например, как ловушки сокетов.

Ибрагим Хаддад, Мирослав Закржевски — специалисты по ИТ. С ними можно связаться по адресу: st@linuxjournal.awi.de.


? AWi Verlag


Листинг 1. sock_sendmsg().

sock_sendmsg
(struck socket *sock, struct msghdr *msg,
 int size)
{
int err;
struct scm_cookie scm;
err=
security_ops ->socket_ops->sendmsg(sock, msg,
 size);
if (err)
return (err);
...
}

Листинг 2. dsi_socket_sendmsg().

int dsi_socket_sendmsg(srtuct socket *sock,
 struct msghdr *msg,
int size)
{
...
inode_security_t *isec;
struck sock sk;
struct ip_options *opt = NULL;
int optlen = NSID_BASE_LEN + NSID_SSID_LEN +
NSID_NODEID_LEN; // 8+_6+6
unsigned char optptr [optlen];
...
sk=sock->sk;
opt=sk->protinfo.af_inet.opt;
dsi_options_fill (isec, optptr, optlen);
dsi_ip_options_get (&opt, optptr, optlen);
opt=xchg (&sk-> protinfo.af_inet.opt);
...
}

Листинг 3.ip_options_compile ().

int
ip_options_compile (struct ip_options *opt,
 struct sk_buff *skb)
{
unsigned char *pp_ptr;
unsigned char *optptr;
...
case IPOPT_CIPSO:
if (security_ops->ip_ops->decode_options (skb,
 optptr, &pp_ptr))
goto error;
break;
...
}

Листинг 4. sock_queue_rcv_skb ().

int
sock_queue_rcv_skb (struct sock *sk, struct
 sk_buff *skb)
{
int err=0;
...
err=security_ops->socket_ops->soc_rcv_skb
 (sk, skb);
if (err)
return (err);
...
}