Автор: Джим Макдоннелл (Jim McDonnell)
Примечания переводчика:
Перевод вдогонку к прошлой статье Пересборка uwsgi с поддержкой Linux Capabilities. Пока искал документацию о том, как скрестить uwsgi и POSIX Capabilities, наткнулся на эту статью. Сразу добавил ссылку в закладки, чтобы впоследствии перевести. Кстати, описанная в этой статье ошибка попадалась коллегам на работе. Я посоветовал просто принудительно переустановить пакет командой apt-get --reinstall install ping и это помогло. Причины были мне понятны, но вот о существовании команд для раздачи "возможностей" я не подозревал: мне почему-то казалось, что программы самостоятельно запрашивают необходимые им привилегии у ядра операционной системы.
Если вы используете свежую версию Linux (время написания заметки - май 2016), вы могли столкнуться с ошибкой утилиты ping:
$ ping somehost ping: icmp open socket: Operation not permittedТак происходит, потому что двоичный файл ping больше не устанавливается с правами setuid. Он не имеет необходимых привилегий для открытия сокета и завершается аварийно. Это легко исправить при помощи команды:
$ sudo setcap cap_net_raw+p /bin/pingПредполагается, что двоичный файл ping находится в /bin/ping. Теперь он работает:
$ ping somehost PING somehost (123.123.123.123) 56(84) bytes of data. 64 bytes from 123.123.123.123: icmp_seq=1 ttl=53 time=9.14 msВы только что добавили возможность - capability к двоичному файлу ping, что дало ping право открыть raw-сокет, который позволил выполнить проверку доступности удалённой системы.
Linux Capabilities - возможности Linux
Возможности Linux позволяют точно управлять видами привилегий, которые может использовать процесс или поток. Традиционно имелось только два уровня привилегий: root и не-root. Процесс, выполняющийся от имени root или суперпользователя, может выполнять с системой любые действия. Процесс, выполняющийся от имени других пользователей, может получить доступ только к тем файлам, которыми он владеет или к которым предоставлен доступ.Ранее, до появления возможностей, ping и другие системные инструменты устанавливались с флагом setuid, позволяющим им работать от имени пользователя root. Вот так:
$ ls -l /bin/ping -rwsr-xr-x 1 root root 44168 May 7 2014 /bin/pingСимвол "s" в строке разрешений соответствует флагу setuid, который означает, что ping будет выполняться с правами пользователя root, даже если он запущен обычным пользователем. Ping требует для работы повышенных привилегий. Вот несколько других программ, которые в Red Hat 6.5 по умолчанию устанавливаются с флагом setuid, который предписывает системе запускать их с правами root:
$ find /bin -perm +4000 -ls 652330 76 -rwsr-xr-x 1 root root 77336 Aug 6 2013 /bin/mount 656520 32 -rwsr-x--- 1 root fuse 32336 Nov 3 2011 /bin/fusermount 652317 36 -rwsr-xr-x 1 root root 36488 Sep 17 2013 /bin/ping6 652333 56 -rwsr-xr-x 1 root root 53472 Aug 6 2013 /bin/umount 652316 40 -rwsr-xr-x 1 root root 40760 Sep 17 2013 /bin/ping 651661 36 -rwsr-xr-x 1 root root 34904 Oct 17 2013 /bin/su
Опасность программ с флагом setuid
Механизм setuid отлично работает и широко распространён. Однако, он обладает низкой безопасностью. Процесс с флагом setuid во время работы получает гораздо больше привилегий, чем ему требуется на самом деле. Утилите ping требуется лишь открыть raw-сокет и права root, полученные ей через флаг setuid, позволяют это сделать, но также дают ей много других прав, которые ей не требуются. Если двоичный файл ping, например, был заменён взломанной версией, то код злоумышленника будет запущен с полными правами суперпользователя.Это одна из причин, по которой предпочтительнее использовать возможности Linux, нежели флаг setuid. Вот почему они с каждым выпуском Linux стали использоваться всё шире.
Наборы возможностей
Выше двоичному файлу ping были выданы права, которые называются cap_net_raw. сap_net_raw - это одна из большого количества возможностей, которых, согласно странице руководства, насчитывается 38 штук.Каждый поток или процесс, обладает тремя наборами связанных с ним возможностей: Permitted - разрешённые, Inheritable - наследуемые и Effective - действующие. В примере выше, символы "+p" в команде "setcap cap_net_raw+p /bin/ping" добавили возможность cap_net_raw к набору разрешённых возможностей двоичного файла ping, которые означают, что последующий процесс (или поток) ping получит соответствующие права. Соотношения наборов возможностей, файлов и потоков, объясняются на соответствующей странице руководства.
CAP_NET_RAW
Возникает вопрос. Если ping для работы требуется определённая возможность или флаг setuid, почему тогда они не требуются другим сетевым утилитам, таким как ssh, ftp, wget и т.д.? И тем более, браузерам вроде Firefox и Safari? Разве им не требуется тоже открывать сетевые сокеты? Да, требуется, но не такие сокеты.Давайте воспользуемся strace и посмотрим, как ping открывает сокет:
$ strace -e socket ping 192.168.1.254 socket(PF_INET, SOCK_RAW, IPPROTO_ICMP) = 3 ...ping открывает сокет типа SOCK_RAW.
Попробуем сделать то же самое с FTP и увидим, что он не открывает сокет типа SOCK_RAW. Он использует сокет типа SOCK_STREAM:
$ strace -e socket ftp 192.168.1.254 socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3 ftp: connect: Connection refusedКак и ожидалось. SOCK_STREAM создаёт полное транспортно-ориентированное подключение через сокет TCP для длительной связи. С другой стороны, SOCK_RAW просто даёт доступ к нижестоящему уровню IP, позволяя ping отправлять пакеты ICMP напрямую.
Таким образом, CAP_NET_RAW позволяет открывать сокет типа SOCK_RAW, но не требуется для сокетов SOCK_STREAM.
ping в различных дистрибутивах Linux
Утилита ping полезна для пользователей, администраторов и разработчиков. В действительности, нет никакого смысла давать к ней доступ только пользователю root. Некоторые дистрибутивы согласны с этим мнением и в них необходимые возможности назначены ping по умолчанию. В более старых выпусках зачастую в ядре имеется поддержка возможностей, но ping не настроен для их использования.Выпуски, в которых утилите ping уже предоставлены возможности:
- Red Hat 7.0, где утилите ping предоставлены возможности cap_net_admin,cap_net_raw+ep
- Raspbian (Debian 8 Jessie) в выпуске мая 2016 года (но не в феврале 2016)
- Red Hat 6.5
- SLES 12 (getcap/setcap по умолчанию не установлены)
- Ubuntu 14.04/Mint 17
1 комментарий:
спасибо, понятно написано. вот ещё пример: у нас на проде команда секьюрити забирает все капабилити у докер-контейнеров, пинг из контейнера пересаёт работать.
Отправить комментарий