Доступ к необработанным сокетам как обычный пользователь на Linux 2.4

Во встроенной системе (ядро 2.4) мне нужен доступ к интерфейсу eth0 через необработанный сокет от процесса, не выполняющегося от имени пользователя root.

Я попытался решить эту проблему, установив возможность CAP_NET_RAW из командной строки и программно используя cap_set_proc(), но оба безуспешно. Кажется, у меня нет разрешения на это, в программе я получаю ошибку EPERM, в командной строке

Не удалось установить ограничение на процесс `1586': (операция не разрешена)

Есть ли более простой способ сделать то, что я хочу? Если нет, какие шаги необходимы для успешной установки возможности CAP_NET_RAW?

РЕДАКТИРОВАТЬ: У меня есть доступ с правами root, но запуск процесса на постоянной основе, как root не вариант. Версия libcap - 1.10, нет бинарного файла setcap, но есть setpcaps.

РЕДАКТИРОВАТЬ - отвечая Джорджу Скопцову:

Если я вас правильно понял, вы предлагаете запустить процесс с помощью setuid, затем установить возможность CAP_NET_RAW и затем отбросить привилегии. Я попробовал это с помощью следующего кода, но, похоже, он не работает, хотя команда caps не возвращает ошибок. С закомментированным seteuid(), raw доступ работает, но только потому, что процесс запущен от имени пользователя root:

cap_t caps = cap_get_proc();
cap_value_t cap_list[1];
cap_list[0] = CAP_NET_RAW;
if (cap_set_flag(caps, CAP_EFFECTIVE, 1, cap_list, CAP_SET) == -1)
{
    printf("cap_set_flag error");
}
if (cap_set_proc(caps) == -1)
{
    printf("cap_set_proc error");
}

if (seteuid(getuid()) != 0) 
{
    printf("seteuid error");
}

function_that_needs_raw_access();

Спасибо за вашу помощь. Крис

4 ответа

Решение

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

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

Во-первых, убедитесь, что эта возможность установлена ​​успешно, когда процесс запускается от имени пользователя root. Тогда используйте

sudo chown root process
sudo chmod ugo+s process 

установить root как владельца процесса и установить setuid флаг. Затем убедитесь, что возможность установлена, когда процесс запущен другими пользователями. Поскольку этот процесс теперь будет иметь все привилегии суперпользователя, вы должны соблюдать меры безопасности и отбросить привилегии, как только ваш код больше не требует этого (после включения CAP_NET_RAW).

Вы можете следовать этому методу, чтобы убедиться, что вы отбрасываете их правильно.

Вы можете дать исполняемой программе возможность использовать CAP_NET_RAW привилегия, не давая ему другие привилегии root.

$ setcap cap_net_raw=pe *program*

Вы не можете дать эту привилегию, не имея этой привилегии. Конечно, root может дать эту привилегию программам.

Процесс должен быть запущен от имени пользователя root или иметь возможности CAP_NET_RAW в исполняемом файле.

Чтобы установить CAP_NET_RAW, вам нужно запустить команду setcap от имени root. После установки вы можете запустить исполняемый файл от имени другого пользователя, и у него будет доступ к перехвату необработанных пакетов.

Если у вас в любом случае нет доступа с правами root, и никто не может получить права доступа с правами root для установки CAP_NET_RAW или setuid root на исполняемый файл, вы не сможете выполнять захват пакетов как пользователь без полномочий root.

TL;DR ИМХО не поддерживается в ядре < 3.0.

Обсуждалась его поддержка в списке рассылки ядра netdev: https://lwn.net/Articles/420800/ и https://lwn.net/Articles/420801/.

И включил его в commit c319b4d76b9e583a5d88d6bf190e079c4e43213d, выпущенный в ядре 3.0:

commit c319b4d76b9e583a5d88d6bf190e079c4e43213d
Author: Vasiliy Kulikov <segoon@openwall.com>
Date:   Fri May 13 10:01:00 2011 +0000

    net: ipv4: add IPPROTO_ICMP socket kind

Follows: v2.6.39-rc2
Precedes: v3.0-rc1

Запуск ping без CAP_NET_RAW (т.е. без возможности настройки или без set-uid) был реализован для ping в ревизии https://github.com/iputils/iputils/commit/87dbb3a5db657d5eae6934707beaf0507980a1c3, выпущенной в iputils s20150815:

commit 87dbb3a5db657d5eae6934707beaf0507980a1c3
Author: Nikos Mavrogiannopoulos <nmav@redhat.com>
Date:   Fri May 29 11:01:00 2015 +0200

    This patch allows running ping and ping6 without root privileges on
    kernels that support it. Almost identical to Lorenzo
    Colitti's original patch except:
    ...

Follows: s20140519
Precedes: s20150815
Другие вопросы по тегам