Comprender las posibilidades en la programación de Linux

Las capacidades permiten evaluar algunos privilegios importantes del sistema en una cadena separada del proceso actual. De esta manera, no necesitará ejecutar una aplicación como Root para acceder a ciertas partes del sistema.

Como una solución que surge de las necesidades, la Sección 25 de POSIX.1e se relaciona con este tema. El desarrollo de los privilegios definidos en esta sección y más se completó con la llegada de la versión 2.6.26 del kernel de Linux. Aquí encontrará todo lo que necesita saber sobre las capacidades del kernel de Linux.

Comprender las posibilidades en la programación de Linux - Linux

Comprender la lógica de la API de capacidades

El control de privilegios en los sistemas basados ​​en Unix consta de dos pasos:

  • Si el propietario actual (identificador de usuario efectivo, EUID) de la aplicación en ejecución es cero, el sistema no verificará la autorización.
  • Si el valor de EUID es diferente de cero, el sistema realizará el proceso de control de acuerdo con los permisos del usuario activo y el grupo de aplicaciones relevante.

Algunas aplicaciones necesitan privilegios más amplios (SUID, SGIT) mientras se ejecutan. Como ejemplo típico, puede considerar passwd. Con él, los usuarios del sistema pueden cambiar sus contraseñas. Sin embargo, para escribir en el archivo etc/shadow, donde se guardan las contraseñas cifradas, es necesario trabajar con los derechos de usuario raíz (es decir, ID de usuario = 0).

Para resolver este problema, la implementación de passwd contiene el bit SUID. Independientemente del usuario que ejecute esta aplicación, el propietario activo (EUID) siempre será Root:

ls -l /usr/bin/passwd

# Output

-rwsr-xr-x. 1 root root 32552 Jul 23 2021 /usr/bin/passwd

La capacidad de ejecutar aplicaciones SUID en el modelo tradicional de autenticación de Unix parece haber resuelto el problema. Sin embargo, los errores graves en las aplicaciones que contienen bits SUID abren la puerta a la ejecución de código no deseado para los usuarios que tienen control total sobre el sistema. La aplicación ideal debería poder ejecutarse sin necesidad de derechos de usuario raíz, si es posible.

El problema no termina solo con el bit SUID. También debe tener derechos de raíz cuando desee escuchar en un puerto TCP o UDP con privilegios inferiores a 1024 en sistemas basados ​​en Unix. Por ejemplo, para poder escuchar en el puerto TCP 80 de un servidor web, debe ejecutar la aplicación como usuario raíz.

A lo largo de los años, se ha comprendido cuán perturbador es ejecutar aplicaciones que brindan un servicio a un entorno de red con una cuenta de usuario con licencia completa. Como solución alternativa, se ha adoptado que solo una parte específica y más pequeña de la aplicación escucha en el puerto privilegiado como raíz y luego cambia la ID del usuario activo a otro usuario para procesos posteriores (por ejemplo, un usuario sin privilegios restringidos). ).

Este sistema, que ha estado en uso durante años, funciona bien con su simplicidad y aún se usa de manera eficiente. Sin embargo, en la actualidad, es posible obtener algunas capacidades adicionales, específicas de la aplicación, a través de la API de capacidades de Linux, sin necesidad de derechos de root, independientemente del sistema mencionado anteriormente. Verificar Algunos usos prácticos y realistas de Linux.

¡Explicación del modelo de capacidades de Linux!

Puede encontrar la implementación más completa de la API de capacidades en el kernel de Linux. Las distribuciones modernas de Linux también intentan usar este nuevo paradigma a nivel del sistema tanto como sea posible.

Por ejemplo, para que una aplicación funcione Ping , debería poder abrir sockets RAW, que generalmente están reservados solo para usuarios raíz. En las distribuciones de Linux más antiguas, el problema es que el bit SUID se asigna a la aplicación para que los usuarios normales puedan usarlo. En estas versiones, cuando elimina el bit SUID de la aplicación e intenta ejecutar la aplicación como un usuario normal, obtiene el siguiente error:

ping 8.8.8.8

# Output

ping: icmp open socket: Operation not permitted

Mientras que en las distribuciones modernas de Linux, ping probablemente no tenga un bit SUID:

ls -l /bin/ping

# Output

-rwxr-xr-x. 1 root root 95232 Jul 25 2021 /bin/ping

Sin embargo, puede ejecutar la aplicación con éxito como un usuario normal. El mecanismo que hace esto posible es que Ping tiene la capacidad especial CAP_NET_RAW.

Puede averiguar las capacidades adicionales de la aplicación usando el comando getcap de la siguiente manera:

sudo getcap /bin/ping

# Output

/bin/ping cap_net_raw=ep

Si el comando getcap devuelve una respuesta vacía, puede establecer este valor manualmente con:

sudo setcap cap_net_raw+ep /bin/ping

modelo de capacidades de proceso

En una aplicación de Linux, las capacidades de cada proceso se agrupan en tres encabezados:

  • Permisible: En este grupo hay una lista de capacidades adicionales que están permitidas para el proceso relacionado. Otorgar el permiso no significa que se pueda usar activamente en ese momento. Es posible incluir licencias aquí en la capacidad efectiva definida por acción adicional.
  • eficaz: Muestra la lista de capacidades que están actualmente activas para el proceso relacionado. A través de funciones auxiliares que organizan el sistema de habilidades, es posible abandonar o restaurar una habilidad. Sin embargo, en cualquier caso, esto solo se puede hacer entre las personas autorizadas que ya están en el grupo permitido.
  • heredable: cuando una aplicación inicia un nuevo proceso, el proceso recién iniciado muestra la lista de capacidades que heredará de la lista permitida.

La lista de capacidades permitidas, efectivas y heredables para ejecutar procesos en cualquier momento se muestra como una máscara de bits en las líneas CapPrm, CapEff y CapInh en el archivo /proc/ /estado. Además, la línea CapBnd contiene la máscara de bits utilizada en el proceso de control de los límites de capacidad.

Por ejemplo, intente leer los valores de una aplicación de shell en ejecución desde el archivo /proc/self/status:

cat /proc/self/status | grep Cap

# Output

CapInh: 0000000000000000

CapPrm: 0000000000000000

CapEff: 0000000000000000

CapBnd: 000001ffffffffff

CapAmb: 0000000000000000

Modelo de capacidad de archivo de Linux

El funcionamiento del sistema de capacidades para archivos depende de los requisitos previos para los cuales estas propiedades se pueden almacenar en la capa del sistema de archivos virtual (VFS). De manera similar al modelo de proceso, las capacidades de archivo se dividen en tres encabezados:

1. Permitido:

El sistema define las capacidades que se permiten para un proceso cuando se ejecuta el ejecutable correspondiente en este grupo.

2. Efectivo

A diferencia del modelo de procesabilidad, este encabezado almacena solo un bit: activo o inactivo. Si el bit está activo, las capacidades especificadas en la lista permitida del archivo se mueven automáticamente a la lista de capacidades activas del proceso relevante cuando se ejecuta ese archivo y se crea un proceso. Si el bit no está activo, no se realiza la transferencia automática de las capacidades permitidas en el archivo al proceso en ejecución.

Sin embargo, si el código de la aplicación relevante se combina con el sistema de posibilidades, puede activar los permisos en el grupo permitido del archivo mediante llamadas al sistema. El objetivo principal de este comportamiento es garantizar que las aplicaciones heredadas que no incluyen el código del sistema de capacidad, el desarrollo a nivel de código de la aplicación pueda funcionar con el sistema de capacidad sin necesidad de realizar ningún cambio en el código fuente.

Puede pensar que las aplicaciones mejor escritas solo usarán las capacidades cuando sea necesario. Si el bit está activo, todas las capacidades de la lista permitida se activan cuando se inicia la aplicación.

3. Es hereditario

Como en el modelo de proceso, se ejecuta el archivo relevante y se produce el proceso. Si se inicia otra aplicación desde dentro del proceso después de eso, se incluirá en la lista permitida del nuevo proceso. En suma, se refiere a una lista de posibilidades heredadas. Verificar Las aplicaciones más importantes e imprescindibles para los usuarios de Linux.

El papel de las capacidades en Linux

Cuando ejecuta un proceso en particular como un usuario normal, no tiene ningún privilegio. Como resultado, solo puede acceder a las secciones que el sistema permite para usuarios normales. La razón principal detrás de esto es reforzar la seguridad del sistema e implementar medidas de protección como estas.

Permitir que todos los usuarios accedan a todos los recursos puede causar una grave vulnerabilidad de seguridad. Sería muy fácil para las personas que usan el sistema con fines maliciosos explotar las debilidades del sistema. Las capacidades de Linux son útiles en estos asuntos. Mejore fácilmente la seguridad de sus aplicaciones con capacidades API compatibles con el kernel.

Las capacidades de Linux son solo uno de los aspectos a considerar para realizar métodos muy efectivos, como dividir los permisos de usuario raíz, asignar diferentes permisos de ME a usuarios sin privilegios y tomar diferentes precauciones sobre los puertos abiertos en los servicios de Internet con servidores Linux. Ahora puedes ver Cómo crear un servidor web en Linux usando una computadora vieja.

Ir al botón superior