URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID3
Нить номер: 76001
[ Назад ]

Исходное сообщение
"Раздел полезных советов: Совместное использование SELinux и ..."

Отправлено auto_tips , 01-Апр-11 03:13 
Используя утилиту [[http://james-morris.livejournal.com/11010.html Secmark]] можно организовать назначение в правилах iptables SELinux-меток для сетевых пакетов, примерно также как осуществляется назначение меток для локальных системных ресурсов. Подобное может использоваться для предотвращения доступа сторонних процессов, не находящихся под контролем SELinux, к определенному классу пакетов. Например, можно указать что запросы на 80 порт (метка http_packet_t) может отправлять только определенный web-браузер (или процесс, имеющий SELinux-метку http_t) и никто иной.

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

   allow MYDOMAIN unlabed_t:packet { send recv };

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

Попытаемся отключить автоматическую установку метки unlabeled_t, которая назначается в Fedora Linux через SELinux-модуль unlabelednet. Если отключить данный набор SELinux-политик, то все подконтрольные SELinux приложения потеряют отправлять и принимать пакеты с меткой unlabeled_t. Чтобы вернуть таким программам возможность работы в сети для них необходимо подготовить соответствующие SELinux-правила и пометить пакеты.


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

Подготовлено три политики доступа к сети:

internal_packet_t: Iptables помечает меткой internal_packet_t все пакеты, отправленные в локальную сеть или приходящие на текущую машину из локальной сети;

dns_external_packet_t: Iptables помечает меткой dns_external_packet_t все внешние обращения к DNS-серверам (udp/tcp порт 53);

external_packet_t: Iptables помечает меткой external_packet_t все остальные пакеты, не подпадающие под первые два правила;


Для упрощения генерации iptables-правил для назначения SELinux-меток был создан скрипт [[http://people.fedoraproject.org/~dwalsh/SELinux/secmark/secm... secmarkgen]]:

  #!/bin/sh -e

  init() {
  # This just tells iptables to apply the same label to incoming packets as it did on outgoing
    echo $IPTABLES -F -t security
    echo $IPTABLES -t security -A INPUT -m state --state ESTABLISHED,RELATED -j CONNSECMARK --restore

  # Apply a label even if its on another port but is related
    echo $IPTABLES -t security -A OUTPUT -m state --state ESTABLISHED,RELATED -j CONNSECMARK --restore
    echo
    return

  }

  start() {
    # Create a chain for each class of packets we have.
    echo "$IPTABLES -t security -X $NAME 2> /dev/null"
    echo "$IPTABLES -t security -N $NAME"
  }

  fini() {
    # Label all other packets going internally to $TYPE:$MCS
    echo $IPTABLES -t security -A $NAME -j SECMARK --selctx system_u:object_r:$TYPE:$MCS
    echo $IPTABLES -t security -A $NAME -j CONNSECMARK --save
    echo $IPTABLES -t security -A $NAME -j ACCEPT
    echo
  }

  setup_network() {

    if [ ! -z "$PORTS" ]; then
    if [ ! -z "$NETWORK" ]; then
            # Send packets going to an $NET httpd to the $NAME chain
        echo $IPTABLES -A OUTPUT -t security -p $PROTOCOL -d $NETWORK --dport $PORTS -j $NAME
        echo $IPTABLES -A INPUT -t security -p $PROTOCOL -d $NETWORK --sport $PORTS -j $NAME
    else
            # Send packets going to $PORTS httpd to the $NAME chain
        echo $IPTABLES -A OUTPUT -t security -p $PROTOCOL --dport $PORTS -j $NAME
        echo $IPTABLES -A INPUT -t security -p $PROTOCOL --sport $PORTS -j $NAME
    fi
    elif [ ! -z "$NETWORK" ]; then
            # Send packets going to $PORT httpd to the $NAME chain
        echo $IPTABLES -A OUTPUT -t security -d $NETWORK -j $NAME
        echo $IPTABLES -A INPUT -t security -s $NETWORK -j $NAME
    else
    echo $IPTABLES -A OUTPUT -t security -j $NAME
    echo $IPTABLES -A INPUT -t security -j $NAME
    fi
  }
  usage() {
           $"""
  Usage: $0 -i
  Usage: $0 -T iptablescmd -P protocol -p port[:...] -N network[,...] -t selinux_type -m MCS NAME
  Usage: $0 -f NAME
  """
  }

  echo
  echo "#---------------"
  echo "# $0 $*"
  echo "#---------------"
  echo
  IPTABLES=iptables
  NAME=
  PORTS=
  MCS=s0
  NETWORK=
  TYPE=client_packet_t
  PROTOCOL=tcp
  FINISH=0
  START=0
  INIT=0

  while getopts "sfin:p:m:t:T:P:" i; do
    case "$i" in
    i)
        INIT=1
        ;;
    s)
        START=1
        ;;
    f)
        FINISH=1
        ;;
    P)
        PROTOCOL=$OPTARG
        ;;
    T)
        IPTABLES=$OPTARG
        ;;
    n)
        export NETWORK=$OPTARG
        ;;
    t)
        export TYPE=$OPTARG
        ;;
    p)
        export PORTS=$OPTARG
        ;;
    m)
        export MCS=$OPTARG
        ;;
    *)
        usage
        exit 1
  esac
  done

  # Init does not require a NAME
  if [ $INIT == 1 ]; then
    init
    exit $?
  fi

  # Move out processed options from arguments
  shift $(( OPTIND - 1 ))

  NAME=$1

  if [ -z "$NAME" -o -z "$MCS" -o -z "$NAME" ]; then
    usage
    exit 1
  fi

  if [ $START == 1 ]; then
    start
    exit $?
  fi

  if [ $FINISH == 1 ]; then
    fini
    exit $?
  fi

  setup_network


Скрипт можно запускать со следующими параметрами:

Инициализируем secmark-метки:
   ./secmarkgen -i

Определяем имя сети (имя Iptables-цепочки):
   ./secmarkgen -s INTERNAL


Привязываем к созданной цепочке набор правил. Синтаксис команды:
   ./secmarkgen -T iptablescmd -P protocol -p port[:...] -N network[,...] -t selinux_type -m MCS NAME

Например:

   ./secmarkgen -n 255.255.255.255,127/8,10.0.0.0/8,172.16.0.0/16,224/24,192.168/16 INTERNAL

Для завершения формирования secmark-правил и их привязки к определенной SELinux-метке используется команда:

   ./secmarkgen -f NAME

Например,

   ./secmarkgen -f -t internal_packet_t INTERNAL

в итоге будет сгенерирован примерно такой скрипт:

   #--------------------
   # ./secmarkgen -i
   #--------------------
   iptables -F -t security

   iptables -t security -A INPUT -m state --state ESTABLISHED,RELATED -j CONNSECMARK --restore

   iptables -t security -A OUTPUT -m state --state ESTABLISHED,RELATED -j CONNSECMARK --restore

   #--------------------
   # ./secmarkgen -s INTERNAL
   #--------------------

   iptables -t security -X INTERNAL 2> /dev/null

   iptables -t security -N INTERNAL

   #--------------------
   # ./secmarkgen -n 255.255.255.255,127/8,10.0.0.0/8,172.16.0.0/16,224/24,192.168/16 INTERNAL
   #--------------------

   iptables -A OUTPUT -t security -d 255.255.255.255,127/8,10.0.0.0/8,172.16.0.0/16,224/24,192.168/16 -j INTERNAL

   iptables -A INPUT -t security -s 255.255.255.255,127/8,10.0.0.0/8,172.16.0.0/16,224/24,192.168/16 -j INTERNAL

   #--------------------
   # ./secmarkgen -f -t internal_packet_t INTERNAL
   #--------------------

   iptables -t security -A INTERNAL -j SECMARK --selctx system_u:object_r:internal_packet_t:s0

   iptables -t security -A INTERNAL -j CONNSECMARK --save

   iptables -t security -A INTERNAL -j ACCEPT


В итоге, для генерации iptables-правил для локальных приложений используется примерно такой скрипт (secmark_test.sh):

   ./secmarkgen -i
   ./secmarkgen -s INTERNAL
   ./secmarkgen -n 255.255.255.255,127/8,10.0.0.0/8,172.16.0.0/16,224/24,192.168/16 INTERNAL
   ./secmarkgen -f -t internal_packet_t INTERNAL
   ./secmarkgen -s DNS
   ./secmarkgen -P udp -p 53 DNS
   ./secmarkgen -P tcp -p 53 DNS
   ./secmarkgen -f -t dns_external_packet_t DNS
   ./secmarkgen -s EXTERNAL
   ./secmarkgen EXTERNAL
   ./secmarkgen -f -t external_packet_t EXTERNAL
   ./secmarkgen -T ip6tables -i
   ./secmarkgen -T ip6tables -s INTERNAL
   ./secmarkgen -T ip6tables -n FEC0::/10,::1/128,FF::/8,FE80::/10FC00::/7 INTERNAL
   ./secmarkgen -T ip6tables -f -t internal_packet_t INTERNAL
   ./secmarkgen -T ip6tables -s EXTERNAL
   ./secmarkgen -T ip6tables EXTERNAL
   ./secmarkgen -T ip6tables -f -t external_packet_t EXTERNAL
  
Генерируем соответствующие iptables-правила:

   ./secmark_test.sh > /tmp/rules

Устанавливать данные iptables-правила пока рано, вначале нужно определить соответствующие указанным меткам (*_packet_t) SELinux-политики, без которых использование данных меток в iptables приведет к выводу ошибки.

Формируем файл с SELinux-политиками (secmark.te):

   policy_module(secmark, 1.0)

   gen_require('

      attribute domain;

      attribute sysadm_usertype;

      # Domains that a staff user could transition to

      attribute staff_usertype;

      attribute telepathy_domain;

      type ping_t;

      type vpnc_t;

      type ssh_t;
  
      type nsplugin_t;

      type mozilla_plugin_t;

      # System domains that want to talk to the external network

      type ntpd_t;

      type sssd_t;

   ')

   # Type Definitions

   attribute external_packet;

   type internal_packet_t;

   corenet_packet(internal_packet_t)

   type dns_external_packet_t, external_packet;

   corenet_packet(dns_external_packet_t)

   type external_packet_t, external_packet;

   corenet_packet(external_packet_t)

   # Allow Rules

   allow domain internal_packet_t:packet { recv send };

   allow sysadm_usertype external_packet:packet { recv send };

   allow staff_usertype external_packet:packet { recv send };

   allow vpnc_t external_packet:packet { recv send };

   allow ssh_t external_packet:packet { recv send };

   allow mozilla_plugin_t external_packet:packet { recv send };

   allow nsplugin_t external_packet:packet { recv send };

   allow telepathy_domain external_packet:packet { recv send };

   allow ping_t external_packet:packet { recv send };

   allow ntpd_t external_packet:packet { recv send };

   dontaudit sssd_t dns_external_packet_t:packet { recv send };


Рассмотрим правила более подробно.
Строка

   policy_module(secmark, 1.0)

определяет имя модуля с политиками.

Далее следует список требований

   gen_require('

      attribute domain;
      ...
      type sssd_t;
   ')

При написании SELinux-политики необходимо сослаться на все типы и атрибуты, чтобы их можно было использовать в правилах. Подобные ссылки указываются в блоке gen_requires. Одновременно можно определить новые типы. Если один из определенных в gen_requires атрибутов или типов будет неопределен в других частях правил, SELinux не активирует созданную политику. Например, атрибут staff_usertype предоставляется всем обслуживающим пользовательским процессам, sysadm_usertype присваивается всем процессам, используемым при администрировании. Домен telepathy_domain охватывает все приложения, связанные с фреймворком telepathy.

Далее в файле следуют правила определения типов и групп. Создаем атрибут external_packet для группировки всех  правил, связанных с внешним трафиком. Также создаем интерфейс corenet_packet для для ассоцииации набора правил с пакетами.

   attribute external_packet;
   type internal_packet_t;
   corenet_packet(internal_packet_t)
   type dns_external_packet_t, external_packet;
   corenet_packet(dns_external_packet_t)
   type external_packet_t, external_packet;
   corenet_packet(external_packet_t)
  

Далее указано правило, разрешающее всем процессам отправку и прием внутренних пакетов из локальной сети:

   allow domain internal_packet_t:packet { recv send };

Следующее правило позволяет запускаемым администраторами программам отправлять и принимать пакеты из внешних сетей (вместо указания  xternal_packet_t в правили фигурирует атрибут external_packet, который позволяет провести действие сразу над группой -  external_packet_t и dns_external_packet_t):


   allow sysadm_usertype external_packet:packet { recv send };
   allow staff_usertype external_packet:packet { recv send };
   allow vpnc_t external_packet:packet { recv send };
   allow ssh_t external_packet:packet { recv send };
   allow mozilla_plugin_t external_packet:packet { recv send };
   allow nsplugin_t external_packet:packet { recv send };
   allow telepathy_domain external_packet:packet { recv send };
   allow ping_t external_packet:packet { recv send };

Для сервиса ntpd заведен отдельный тип ntp_external_packet_t:

   allow ntpd_t external_packet:packet { recv send };

Для программы sssd запрещаем общение с системами за пределами приватной сети:

   dontaudit sssd_t dns_external_packet_t:packet { recv send };


Теперь приступим к компиляции, установке и применению созданной SELinux-политики:

Компилируем:

   make -f /usr/share/selinux/devel/Makefile

Устанавливаем:

   semodule -i secmark.pp

Активируем iptables-правила:

   sh /tmp/rules

Сохраняем внесенные изменения:

   service iptables save
   service ip6tables save

С этого момента каждому сетевому пакету присваивается одна из трех созданных SELinux-меток. Для отладки следует проследить за появлением avc-сообщений и при необходимости добавить исключения с использованием правил allow/dontaudit или расследовать причину появления непрошеного трафика.

URL: http://www.linux.com/learn/tutorials/421152-using-selinux-an...
Обсуждается: http://www.opennet.me/tips/info/2552.shtml


Содержание

Сообщения в этом обсуждении
"Совместное использование SELinux и iptables"
Отправлено yurii , 01-Апр-11 03:13 
всё круто, вот только автор не поленился бы пройтись по "переводу" прежде чем постить ...

"Совместное использование SELinux и iptables"
Отправлено hostmaster , 04-Апр-11 11:57 
совершенно зря опущено описание use case где автор рассказывает зачем он это делает.

"Совместное использование SELinux и iptables"
Отправлено crypt , 19-Апр-11 21:59 
>"Всем программ, запущенные в рамках сессии

пользователя, разрешено обращаться как ко внутренним, так и к внешним сетевым ресурсам."

Т.е. малваре запущенное во время сеанса пользователя будет иметь доступ в Интеренет? А смысл тогда этого всего? От чего хотел обезопасить себя автор???