На днях стало известно о том, что Линус Торвальдс одобрил добавление новой функции безопасности в ядро Linux. Она называется Lockdown и предназначена для ограничения прав суперпользователя. Появится функция в версии ядра 5.4, причем речь идет именно о «ванильном» ядре, а не дистрибутивах.

Функцию добавят в виде модуля безопасности LSM (Linux Security Module). В результате процессы, которые запущены в пространстве пользователя, будут разграничены более жестко, с кодом ядра запретят взаимодействовать даже привилегированным аккаунтам.

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

В настоящее время киберпреступник, который получает права суперпользователя, получает возможность выполнить произвольный код на уровне ядра. А для этого ему требуется просто записать этот код в память ядра через виртуальное устройств /dev/mem либо же выполнить подмену уже запущенного ядра свой копией, воспользовавшись механизмом kexec. Таким образом, взломщик получит доступ к конфиденциальным данным, которые хранятся на уровне ядра, либо же обойдет механизм безопасной загрузки UEFI Secureboot, одновременно скрыв факт своего присутствия в системе.

А вот активация модуля Lockdown позволяет заблокировать доступ пользовательских процессов к памяти ядра через /dev/kmem и /dev/port. Кроме того, выполняется запрет на выполнение системных вызовов, которые используются для загрузки нового ядра (kexec_load, k_exec_file_load). Есть и ограничение на возможности по изменению режима портов ввода/вывода, плюс ряд других возможностей.

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

Что касается идеи внедрения Lockdown, то у этого процесса долгая история, которая началась еще в 2010 году. Изначально проект возглавлял Мэтью Гаррет, который предложил разработать и внедрить такой механизм обеспечения безопасности, который не даст другим пользователям вмешиваться в работу ядра ОС.

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

Но в 2018 году Торвальдс принял решение согласиться с мнением сообщества, после чего внедрение Lockdown в ванильное ядро стало лишь вопросом времени.

Кстати, Линус Торвальдс долгое время не соглашался с точкой зрения некоторых специалистов по кибербезопасности, которые предлагали тем либо иным образом влиять на работу ядра. В 2017 году один из разработчиков предложил внести в версию ядра v4.15-rc1 созданный им механизм hardened usercopy.

Торвальдс тогда отреагировал крайне жестко, заявив, что специалисты по безопасности должны заниматься своим делом, то есть устранять уязвимости. А вот поиском возможностей изменить работу ядра они заниматься не должны, это прерогатива других экспертов. Линус Торвальдс тогда назвал предложения Кука убийством ядра.

Комментарии (34)


  1. Evengard
    06.10.2019 05:32

    UAC — теперь и в Linux…
    А кстати как защищается эта штука от отключения из-под суперюзера? На крайняк суперюзер может, наверное, поменять настройки на диске и просто отправить машину в ребут. У суперюзера всё равно же остаётся полный доступ к диску. SecureBoot тут врядли спасёт — он просто может подсунуть "ванильное" ядро где эта штука выключена, и при этом подписана стандартными ключами...


    1. ValdikSS
      06.10.2019 07:12

      SecureBoot тут врядли спасёт — он просто может подсунуть «ванильное» ядро где эта штука выключена, и при этом подписана стандартными ключами...
      В популярных дистрибутивах эти патчи используются уже много лет, придётся поискать подписанное ядро и подписанный загрузчик к нему.
      Спойлер: сложно, но возможно.


    1. firk
      07.10.2019 18:00

      UAC — теперь и в Linux…

      Это не UAC, это стырили kern.securelevel из BSD который там нативно всегда был. Но стырили в каком-то обрезанном варианте, впрочем как всегда у линукса.


      А кстати как защищается эта штука от отключения из-под суперюзера?

      Никак, это не её зона ответственности. Это не "готовое решение" а просто одна из настроек. В комплексе с другими возможно можно построить систему защиты.
      В нормальных системах (BSD) это естественно давно уже есть в удобном виде.


    1. Oplkill
      07.10.2019 22:15

      а что плохого в UAC?
      Имхо в линуксе его наоборот недостаёт, всё-время вводить пароль вместо того, чтобы просто нажать ДА/НЕТ надоедает, особенно если у тебя нормальный сложный пароль


  1. qw1
    06.10.2019 11:46

    То как-то администраторы могут устанавливать новые драйверы?
    Или драйверы должны быть подписаны, но тогда кто центр доверия?


    1. atbuhw
      06.10.2019 14:57

      Я надеюсь (описание ограниченных функций в статье создаёт такое впечатление), что все эти ограничения относятся только к доступу к уже работающему ядру. Тогда они не должны мешать смонитровать /boot, записать туда то, что нужно и перезагрузиться.


    1. ValdikSS
      07.10.2019 04:20

      Да, по умолчанию insmod неподписанных модулей блокируется, если включён Secure Boot. Однако, в этих дистрибутивах есть механизмы автоматической(!) генерации и добавления своего локального ключа в ~Secure Boot (в Shim MOK на самом деле, но неважно), которые применяются, например, для DKMS-модулей. Пользователю нужно только единожды подтвердить добавление ключа при первой перезагрузке после генерации локального ключа.
      Такое уже много лет в Ubuntu, например.


      1. monah_tuk
        07.10.2019 08:43

        Мы так подписываем свой драйвер после "отстройки" на пользовательской машине. Если честно, то смысла реагировать на неподписанные модули в таком раскладе не вижу никакого. Т.е. на защищённой машине не должно быть DKMS и все сторонние драйвера подписывать в удостоверяющем центре (но тогда беда с обновлениями самого ядра). В противном случае вся эта защита — это стальная дверь в бумажных стенах.


  1. sumanai
    06.10.2019 14:20

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


    1. qw1
      06.10.2019 16:29

      Да всегда сетевые сервисы крутились под своим юзером типа www, и никаких прав не требовали. Скорее всего, сабжевая проблема возникла на десктопных сценариях, когда юзер всегда сидит с правами root и не желает делать лишние телодвижения ради безопасности.


      1. sumanai
        06.10.2019 18:28
        +1

        Для приёма соединений по портам меньше 1000 нужны рут права. И череда взломов Exim показывает, что проблема всё же есть.


        1. qw1
          06.10.2019 20:20

          Сколько видел конфигураций, веб-сервер никто под рутом не пускает. Проблема с портами как-то решается, через тот же inetd


          1. andreymal
            06.10.2019 20:33
            -2

            Где можно посмотреть такие конфигурации? Сколько видел конфигураций — везде веб-серверы от рута работают. Как минимум во всех дебианах веб-серверы из коробки настроены на работу от рута.


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


            1. qw1
              06.10.2019 21:19
              +1

              А, вот оно в чём дело. Всякие php и прочие cgi уже работают не от рута. Я думал, они наследуют права сервера.


              1. andreymal
                06.10.2019 21:27
                +1

                То, что всякие php и прочие cgi работают не от рута, это, конечно, хорошо, но возможные уязвимости в мастер-процессах apache2/nginx к сожалению тоже никто не отменял (из последних CVE-2019-0211 например)


            1. atbuhw
              07.10.2019 14:57
              +1

              Где можно посмотреть такие конфигурации?
              Если su не нужно (например, сайт без регистрации пользователей на VPS), то проблема самого приёма подключений на порт 80 или 443 решается с помощью iptables и REDIRECT/DNAT.


          1. sumanai
            06.10.2019 22:40

            Ну не знаю
            root 6556 0.0 0.3 183328 3848 ? Ss Aug22 0:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
            root 13677 0.0 0.6 363588 6712 ? Ss Aug16 9:15 php-fpm: master process (/etc/php/7.2/fpm/php-fpm.conf)

            Воркеры конечно работают от ограниченных пользователей, а вот про inetd ничего не слышал.


            1. qw1
              06.10.2019 22:54

              а вот про inetd ничего не слышал
              Например, сервер firebird так работает: inetd слушает порт 3050, а процессы fb_inet_server запускаются из inetd не с рутом. Я думал, это стандартная практика для сетевых сервисов.


              1. sumanai
                07.10.2019 00:24

                inetd слушает порт 3050

                Но ведь это непривилегированный порт.


              1. eumorozov
                07.10.2019 06:25

                Это еще и неэффективно, так как при каждом входящем соединении inetd запускает процесс сервера. А запуск процесса — долгая и дорогостоящая операция. Поэтому большинство серверов реализованы так, чтобы выполняться и слушать порт постоянно, не через inetd.


        1. Prototik
          06.10.2019 22:58
          +1

          Для приёма соединений нужен CAP_NET_BIND_SERVICE, а не рут права. Да и есть куча методов обхода этого (если по каким-то причинам не смогли в capabilities).


          1. monah_tuk
            07.10.2019 08:57

            Это если совсем без root. Если нет, то вполне можно использовать классический подход с запуском от root, созданием сокета, началом слушания его и последующим сбросом прав. Но так да, CAP_NET_BIND_SERVICE ставится на бинарь один раз и всё, дальше только не забыть переустанавливать по обновлению.


            1. Prototik
              07.10.2019 16:27

              Не обязательно на бинарь, его можно прописать в юнит systems, и тогда обновления нормально проходят.


              1. monah_tuk
                08.10.2019 04:48

                Да, точно, такой вариант в голову не пришёл.


        1. monah_tuk
          07.10.2019 08:44

          del


      1. RH215
        06.10.2019 21:39

        Ну очень далеко не всегда это делается. Особенно если сервис работает не через веб-сервер. В контейнерах так вообще редко процессы запускаются не от рута.


  1. Victor_koly
    06.10.2019 14:47

    через /dev/kmem, /dev/kmem и /dev/port


    Беглое гугление незнакомой темы (а точнее — глянул ссылку) предполагает, что одним из «устройств» здесь было /dev/mem.


  1. Alex_ME
    07.10.2019 01:42

    А что мешает выполнить insmod и загрузить модуль, который делает что хочешь?




  1. Andrey_Rogovsky
    07.10.2019 10:40

    GrSecurity плавно мигрирует в main ветку.


  1. SamsonovAnton
    09.10.2019 00:45

    Кто готов пожертвовать свободой ради безопасности, не достоин ни свободы, ни безопасности.
    Зашёл сюда увидеть эту расхожую на Хабре цитату, но почему-то не увидел. Как можно променять пьянящий дух свободы невозбранно отстрелить себе ногу на уютненький островок безопасности посреди болотца?


    1. Am0ralist
      09.10.2019 10:18

      Те, кто готов пожертвовать насущной свободой ради кратковременной безопасности, не достойны ни свободы, ни безопасности. (Those who would give up essential Liberty, to purchase a little temporary Safety, deserve neither Liberty nor Safety.)
      Наверное, поэтому?
      А вообще, доказательство цитатами, вырванными из контекста — это все равно что цитировать Ленина:
      Большой ошибкой было бы думать...


    1. atbuhw
      09.10.2019 16:41

      К чему здесь эта цитата? Как я понимаю, конфигурировать ядро я могу любым способом: так, что при следующей загрузке я получу либо полный рут, либо «урезанный». При этом даже в режиме «урезанного» рута ничего не мешает мне пересобрать ядро ещё раз, с новыми, неурезаннанными параметрами, и после следующей перезагрузки я получу снова полный рут. Какую свободу я теряю? Это всё равно что утверждать, что при логине под обычным пользователем я не достоин ни свободы, ни безопасности.