dmesg: чтение буфера ядра завершилось неудачно — операция не позволена

Команда dmesg в ответ выдаёт строку «чтение буфера ядра завершилось неудачно: Операция не позволена» — это означает, что ядро Linux заблокировало доступ к кольцевому буферу сообщений для вашего пользователя. Чаще всего причина — активированный параметр kernel.dmesg_restrict, который запрещает непривилегированным пользователям читать логи ядра. Ошибка не говорит о поломке системы: это защитный механизм, который можно обойти через sudo или настройкой sysctl.

Ниже разберём, почему возникает ограничение, как быстро восстановить доступ к сообщениям ядра и в каких случаях ошибка появляется даже при использовании sudo. Инструкции применимы к большинству дистрибутивов — Ubuntu, Debian, Fedora, Arch Linux и другим, поскольку механизм реализован на уровне ядра.

Почему dmesg отказывает в доступе к буферу ядра

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

Проверить текущее состояние параметра можно командой:

cat /proc/sys/kernel/dmesg_restrict

Если вывод равен 1 — ограничение активно, и только root (или процесс с capability CAP_SYSLOG) может читать буфер. Значение 0 означает, что доступ открыт всем пользователям.

  • 🔒 kernel.dmesg_restrict=1 — основная и самая частая причина ошибки;
  • 🐧 запуск dmesg без sudo от имени обычного пользователя;
  • 📦 работа внутри контейнера (Docker, LXC) без нужных привилегий;
  • 🛡️ политики SELinux или AppArmor, блокирующие доступ к /dev/kmsg;
  • 🔑 отсутствие capability CAP_SYSLOG у процесса.

Быстрое решение: запуск через sudo

Самый простой способ — выполнить команду с правами суперпользователя. Вам потребуется доступ к sudo и пароль учётной записи:

sudo dmesg

Для удобного чтения добавьте полезные флаги: -T выводит метки времени в человекочитаемом формате, -H включает постраничный просмотр, -l err покажет только ошибки:

sudo dmesg -T | less

Если и с sudo появляется та же ошибка — вероятно, вы работаете в контейнере, чруте или среде с урезанными привилегиями. Об этом подробнее в отдельном разделе ниже.

Постоянное отключение ограничения через sysctl

Если требуется, чтобы dmesg работал без sudo постоянно, измените значение параметра kernel.dmesg_restrict. Для временного изменения (до перезагрузки) выполните:

sudo sysctl kernel.dmesg_restrict=0

Чтобы настройка сохранилась после перезагрузки, создайте файл в каталоге /etc/sysctl.d/ и запишите параметр туда:

echo "kernel.dmesg_restrict=0" | sudo tee /etc/sysctl.d/10-dmesg.conf

sudo sysctl --system

После этого обычный пользователь сможет вызывать dmesg без повышения привилегий. Проверьте результат командой dmesg | head — должен появиться вывод сообщений ядра.

⚠️ Внимание: отключение dmesg_restrict снижает защиту системы. Логи ядра могут содержать адреса памяти ядра, которые используются при атаках на повышение привилегий. На многопользовательских и публично доступных серверах оставляйте значение 1 и работайте через sudo.

☑️ Настройка доступа к dmesg

Выполнено: 0 / 5

Сравнение способов доступа к логам ядра

Кроме dmesg, сообщения ядра доступны и другими путями. Выбор зависит от дистрибутива и задачи:

СпособКомандаНужен rootОсобенности
dmesgsudo dmesgДа (при restrict=1)Только текущий буфер ядра
journalctljournalctl -kЗависит от группИстория загрузок, фильтры
/dev/kmsgsudo cat /dev/kmsgДаСырой поток сообщений
Лог-файлы/var/log/kern.logДаЕсть не во всех дистрибутивах

Обратите внимание на journalctl: в системах с systemd пользователи, входящие в группу systemd-journal или adm, могут читать логи ядра командой journalctl -k даже без root. Добавить себя в группу можно так:

sudo usermod -aG systemd-journal $USER

Изменение вступит в силу после повторного входа в систему. Это более безопасная альтернатива полному отключению dmesg_restrict.

📊 Как вы решаете проблему доступа к dmesg?
Использую sudo dmesg
Отключил dmesg_restrict
Читаю логи через journalctl
Работаю в контейнере, проблема не решена

Ошибка внутри контейнеров Docker и LXC

В контейнерах ситуация сложнее: даже root внутри контейнера обычно не имеет доступа к буферу ядра хоста, поскольку ядро общее, а capability CAP_SYSLOG по умолчанию не выдаётся. В этом случае dmesg будет возвращать «операция не позволена» независимо от значения dmesg_restrict.

Возможные варианты действий:

  • 🐳 запуск контейнера с флагом --privileged — даёт полный доступ, но снижает изоляцию;
  • 🔧 точечное добавление capability: docker run --cap-add SYSLOG ...;
  • 📋 чтение логов ядра на хосте, а не внутри контейнера — предпочтительный вариант.
⚠️ Внимание: флаг --privileged предоставляет контейнеру практически неограниченный доступ к хосту. Используйте его только в доверенной среде; для чтения логов ядра достаточно отдельной capability SYSLOG.
Что такое capability CAP_SYSLOG

В ядрах Linux начиная с версии 2.6.37 доступ к syslog-интерфейсу был вынесен из CAP_SYS_ADMIN в отдельную capability CAP_SYSLOG. Это позволяет выдать процессу право читать логи ядра, не давая ему полный набор административных привилегий.

Диагностика, если ничего не помогло

Если sudo dmesg на обычной системе (не в контейнере) по-прежнему возвращает ошибку, необходимо проверить дополнительные механизмы безопасности. В дистрибутивах с SELinux (Fedora, RHEL, CentOS) посмотрите отказы в аудите:

sudo ausearch -m avc -ts recent | grep dmesg

В системах с AppArmor (Ubuntu) проверьте журнал на предмет DENIED-записей: sudo journalctl -e | grep -i denied. Также убедитесь, что бинарный файл dmesg не повреждён и не заменён обёрткой: which dmesg должен показывать стандартный путь вроде /usr/bin/dmesg или /bin/dmesg.

Ещё одна возможная причина — ядро, собранное с опцией CONFIG_SECURITY_DMESG_RESTRICT, принудительно включает ограничение, и значение по умолчанию может отличаться от привычного. В таком случае управляйте параметром только через sysctl, как описано выше.

Часто задаваемые вопросы

Почему dmesg раньше работал без sudo, а теперь выдаёт ошибку?

Вероятнее всего, обновление системы или смена настроек безопасности установили kernel.dmesg_restrict=1. Проверьте текущее значение через cat /proc/sys/kernel/dmesg_restrict и при необходимости измените его через sysctl.

Безопасно ли отключать dmesg_restrict на домашнем компьютере?

На однопользовательской домашней системе риск невелик, однако рекомендуется оставить ограничение и использовать sudo dmesg — это не требует дополнительных настроек и сохраняет защиту от утечки адресов памяти ядра.

Чем dmesg отличается от journalctl -k?

dmesg показывает только текущий кольцевой буфер ядра, который перезаписывается по мере заполнения. journalctl -k читает сообщения ядра из журнала systemd, где могут сохраняться данные прошлых загрузок (при включённом постоянном хранилище журнала).

Можно ли дать доступ к dmesg одному пользователю без root?

Да. Добавьте пользователя в группу systemd-journal для доступа через journalctl -k, либо настройте правило sudoers, разрешающее конкретному пользователю выполнять sudo dmesg без пароля.

Ошибка появляется в Docker-контейнере даже под root. Что делать?

Это ожидаемое поведение: ядро общее с хостом, и контейнеру не выдана capability CAP_SYSLOG. Запустите контейнер с --cap-add SYSLOG или читайте логи ядра непосредственно на хост-системе.