it-swarm-es.com

¿Qué permisos deben tener los archivos / carpetas de mi sitio web en un servidor web Linux?

Esta es una Pregunta canónica sobre permisos de archivos en un servidor web Linux.

Tengo un servidor web Linux que ejecuta Apache2 que aloja varios sitios web. Cada sitio web tiene su propia carpeta en/var/www /.

/var/www/contoso.com/
/var/www/contoso.net/
/var/www/fabrikam.com/

El directorio base/var/www/es propiedad de root: root. Apache se ejecuta como www-data: www-data. El sitio web de Fabrikam es mantenido por dos desarrolladores, Alice y Bob. Ambos sitios web de Contoso son mantenidos por un desarrollador, Eve. Todos los sitios web permiten a los usuarios subir imágenes. Si un sitio web se ve comprometido, el impacto debe ser lo más limitado posible.

Quiero saber la mejor manera de configurar permisos para que Apache pueda servir el contenido, el sitio web esté a salvo de ataques y los desarrolladores aún puedan realizar cambios. Uno de los sitios web está estructurado así:

/var/www/fabrikam.com
    /cache
    /modules
    /styles
    /uploads
    /index.php

¿Cómo deben establecerse los permisos en estos directorios y archivos? Leí en alguna parte que nunca deberías usar permisos 777 en un sitio web, pero no entiendo qué problemas podrían causar. Durante los períodos ocupados, el sitio web almacena en caché automáticamente algunas páginas y almacena los resultados en la carpeta de caché. Todo el contenido enviado por los visitantes del sitio web se guarda en la carpeta de cargas.

324
Nic

Al decidir qué permisos usar, debe saber exactamente quiénes son sus usuarios y qué necesitan. Un servidor web interactúa con dos tipos de usuarios.

Los usuarios autenticados tienen una cuenta de usuario en el servidor y se les puede proporcionar privilegios específicos. Esto generalmente incluye administradores de sistemas, desarrolladores y cuentas de servicio. Por lo general, realizan cambios en el sistema mediante SSH o SFTP.

Los usuarios anónimos son los visitantes de su sitio web. Aunque no tienen permisos para acceder a los archivos directamente, pueden solicitar una página web y el servidor web actúa en su nombre. Puede limitar el acceso de usuarios anónimos si tiene cuidado con los permisos que tiene el proceso del servidor web. En muchas distribuciones de Linux, Apache se ejecuta como www-data usuario pero puede ser diferente. Utilizar ps aux | grep httpd o ps aux | grep Apache para ver qué usuario está usando Apache en su sistema.


Notas sobre permisos de Linux

Linux y otros sistemas compatibles con POSIX utilizan los permisos tradicionales de Unix. Hay un excelente artículo en Wikipedia sobre permisos del sistema de archivos , así que no repetiré todo aquí. Pero hay algunas cosas que debe tener en cuenta.

El bit de ejecución
Los scripts interpretados (p. Ej., Ruby, PHP) funcionan bien sin el permiso de ejecución. Solo los binarios y los scripts de Shell necesitan el bit de ejecución. Para atravesar (ingresar) un directorio, debe tener permiso de ejecución en ese directorio. El servidor web necesita este permiso para enumerar un directorio o servir cualquier archivo dentro de él.

Permisos predeterminados de archivos nuevos
Cuando se crea un archivo, normalmente hereda la identificación de grupo de quien lo creó. Pero a veces desea que los archivos nuevos hereden la identificación del grupo de la carpeta donde se crean, por lo que habilitaría el bit SGID en la carpeta principal.

Los valores de permiso predeterminados dependen de su umask. El umask resta permisos de los archivos recién creados, por lo que el valor común de 022 da como resultado que los archivos se creen con 755. Cuando colabora con un grupo, es útil cambiar su umask a 002 para que los miembros del grupo puedan modificar sus archivos. Y si desea personalizar los permisos de los archivos cargados, debe cambiar la umask para Apache o ejecutar chmod después de que se haya cargado el archivo.


El problema con 777

Cuando usted chmod 777 su sitio web, no tiene seguridad alguna. Cualquier usuario en el sistema puede cambiar o eliminar cualquier archivo en su sitio web. Pero más en serio, recuerde que el servidor web actúa en nombre de los visitantes de su sitio web, y ahora el servidor web puede cambiar los mismos archivos que está ejecutando. Si hay vulnerabilidades de programación en su sitio web, pueden explotarse para desfigurar su sitio web, insertar ataques de phishing o robar información de su servidor sin que usted lo sepa.

Además, si su servidor se ejecuta en un puerto conocido (que debería evitar que los usuarios no root generen servicios de escucha accesibles desde el mundo), eso significa que su servidor debe ser iniciado por root ( aunque cualquier servidor en su sano juicio caerá inmediatamente a una cuenta menos privilegiada una vez que el puerto esté vinculado). En otras palabras, si está ejecutando un servidor web donde el ejecutable principal es parte del control de versión (por ejemplo, una aplicación CGI), dejando sus permisos (o, en realidad, los permisos del directorio que contiene, ya que el usuario podría cambiar el nombre el ejecutable) en 777 permite cualquier usuario ejecutar cualquier ejecutable como root .


Definir los requisitos.

  • Los desarrolladores necesitan acceso de lectura/escritura a los archivos para poder actualizar el sitio web
  • Los desarrolladores necesitan leer/escribir/ejecutar en directorios para poder navegar
  • Apache necesita acceso de lectura a archivos y scripts interpretados
  • Apache necesita acceso de lectura/ejecución a directorios que se pueden servir
  • Apache necesita acceso de lectura/escritura/ejecución a los directorios para el contenido cargado

Mantenido por un solo usuario

Si solo un usuario es responsable de mantener el sitio, configúrelo como el propietario del usuario en el directorio del sitio web y otorgue al usuario permisos completos de rwx. Apache todavía necesita acceso para poder servir los archivos, así que configure www-data como el propietario del grupo y otorgue permisos de grupo r-x.

En su caso, Eve, cuyo nombre de usuario podría ser eve, es el único usuario que mantiene contoso.com:

chown -R eve contoso.com/
chgrp -R www-data contoso.com/
chmod -R 750 contoso.com/
chmod g+s contoso.com/
ls -l
drwxr-s--- 2 eve      www-data   4096 Feb  5 22:52 contoso.com

Si tiene carpetas que Apache puede escribir, puede modificar los valores de permiso para el propietario del grupo para que www-data tenga acceso de escritura.

chmod g+w uploads
ls -l
drwxrws--- 2 eve      www-data   4096 Feb  5 22:52 uploads

El beneficio de esta configuración es que se hace más difícil (pero no imposible *) que otros usuarios en el sistema puedan husmear, ya que solo los usuarios y los propietarios del grupo pueden navegar por el directorio de su sitio web. Esto es útil si tiene datos secretos en sus archivos de configuración. ¡Ten cuidado con tu umask! Si crea un nuevo archivo aquí, los valores de los permisos probablemente serán por defecto 755. Puede ejecutar umask 027 para que los nuevos archivos tengan un valor predeterminado de 640 (rw- r-- ---).


Mantenido por un grupo de usuarios

Si más de un usuario es responsable del mantenimiento del sitio, deberá crear un grupo para asignar permisos. Es una buena práctica crear un grupo separado para cada sitio web y nombrar el grupo después de ese sitio web.

groupadd dev-fabrikam
usermod -a -G dev-fabrikam alice
usermod -a -G dev-fabrikam bob

En el ejemplo anterior, utilizamos el propietario del grupo para otorgar privilegios a Apache, pero ahora eso se usa para el grupo de desarrolladores. Dado que el propietario del usuario ya no es útil para nosotros, configurarlo como root es una forma simple de garantizar que no se filtren privilegios. Apache todavía necesita acceso, por lo que le damos acceso de lectura al resto del mundo.

chown -R root fabrikam.com
chgrp -R dev-fabrikam fabrikam.com
chmod -R 775 fabrikam.com
chmod g+s fabrikam.com
ls -l
drwxrwxr-x 2 root     dev-fabrikam   4096 Feb  5 22:52 fabrikam.com

Si tiene carpetas que deben ser grabables por Apache, puede hacer que Apache sea el propietario del usuario o el propietario del grupo. De cualquier manera, tendrá todo el acceso que necesita. Personalmente, prefiero que sea el propietario del usuario para que los desarrolladores puedan seguir explorando y modificando el contenido de las carpetas cargadas.

chown -R www-data uploads
ls -l
drwxrwxr-x 2 www-data     dev-fabrikam   4096 Feb  5 22:52 uploads

Aunque este es un enfoque común, hay un inconveniente. Dado que todos los demás usuarios del sistema tienen los mismos privilegios para su sitio web que Apache, es fácil para otros usuarios explorar su sitio y leer archivos que pueden contener datos secretos, como sus archivos de configuración.

Puedes tener tu pastel y comértelo también

Esto se puede mejorar aún más. Es perfectamente legal que el propietario tenga menos privilegios que el grupo, por lo que en lugar de desperdiciar al propietario del usuario asignándolo a la raíz, podemos hacer que Apache sea el propietario del usuario en los directorios y archivos de su sitio web. Esto es una inversión del escenario de mantenedor único, pero funciona igualmente bien.

chown -R www-data fabrikam.com
chgrp -R dev-fabrikam fabrikam.com
chmod -R 570 fabrikam.com
chmod g+s fabrikam.com
ls -l
dr-xrwx--- 2 www-data  dev-fabrikam   4096 Feb  5 22:52 fabrikam.com

Si tiene carpetas que Apache puede escribir, puede modificar los valores de permiso para el propietario del usuario para que www-data tenga acceso de escritura.

chmod u+w uploads
ls -l
drwxrwx--- 2 www-data  dev-fabrikam   4096 Feb  5 22:52 fabrikam.com

Una cosa a tener en cuenta con esta solución es que el usuario propietario de los nuevos archivos coincidirá con el creador en lugar de configurarlo en www-data. Por lo tanto, Apache no podrá leer los archivos nuevos que cree hasta que los haya creado.


* Separación de privilegios de Apache

Mencioné anteriormente que en realidad es posible que otros usuarios husmeen su sitio web sin importar qué tipo de privilegios esté utilizando. De manera predeterminada, todos los procesos de Apache se ejecutan como el mismo usuario de www-data, por lo que cualquier proceso de Apache puede leer archivos de todos los otros sitios web configurados en el mismo servidor y, a veces, incluso hacer cambios. Cualquier usuario que pueda hacer que Apache ejecute un script puede obtener el mismo acceso que tiene el propio Apache.

Para combatir este problema, hay varios enfoques para separación de privilegios en Apache. Sin embargo, cada enfoque viene con varios inconvenientes de rendimiento y seguridad. En mi opinión, cualquier sitio con requisitos de seguridad más altos debe ejecutarse en un servidor dedicado en lugar de usar VirtualHosts en un servidor compartido.


Consideraciones adicionales

No lo mencioné antes, pero generalmente es una mala práctica tener desarrolladores que editen el sitio web directamente. Para sitios más grandes, es mucho mejor tener algún tipo de sistema de lanzamiento que actualice el servidor web a partir del contenido de un sistema de control de versiones. El enfoque de mantenedor único es probablemente ideal, pero en lugar de una persona tiene un software automatizado.

Si su sitio web permite cargas que no necesitan ser entregadas, esas cargas deben almacenarse en algún lugar fuera de la raíz web. De lo contrario, es posible que las personas estén descargando archivos destinados a ser secretos. Por ejemplo, si permite que los estudiantes envíen tareas, deben guardarse en un directorio que Apache no sirve. Este también es un buen enfoque para los archivos de configuración que contienen secretos.

Para un sitio web con requisitos más complejos, es posible que desee considerar el uso de Listas de control de acceso . Estos permiten un control mucho más sofisticado de los privilegios.

Si su sitio web tiene requisitos complejos, puede escribir un script que configure todos los permisos. Pruébelo a fondo, luego manténgalo seguro. Podría valer su peso en oro si alguna vez necesita reconstruir su sitio web por alguna razón.

347
Nic

Me pregunto por qué tanta gente usa (o recomienda) la "otra" (o) parte de los derechos de Linux para controlar lo que puede hacer Apache (y/o PHP). Al establecer esta parte correcta en algo más que "0", simplemente permite que todo el mundo haga algo en el archivo/directorio.

Mi enfoque es el siguiente:

  • Creo dos usuarios separados. Uno para el acceso SSH/SFTP (si es necesario), que será el propietario de todos los archivos, y otro para el PHP usuario FastCGI (el usuario en el que se ejecutará el sitio web). Llamemos a estos usuarios respectivamente bob y bob-www.
  • bob tendrá todos los derechos (rwx en carpetas, rw - en archivos), para que pueda leer y editar todo el sitio web.
  • El proceso PHP FastCGI necesita r-x derechos en carpetas y r - derechos en archivos, excepto carpetas muy específicas como cache/ o uploads/, donde también se necesita el permiso de "escritura". Para dar a esta habilidad PHP FastCGI), se ejecutará como bob-www, y bob-www se agregará a la creada automáticamente - bob grupo.
  • Ahora nos aseguramos de que el propietario y el grupo de todos los directorios y archivos sean bob bob.
  • Falta algo: incluso usamos FastCGI, pero Apache aún necesita acceso de lectura, para contenido estático o archivos .htaccess que intentará leer si AllowOverride está configurado en algo más que None. Para evitar usar la parte o de los derechos, agrego el usuario www-data al grupo bob.

Ahora:

  • Para controlar lo que puede hacer el desarrollador, podemos jugar con la parte de los derechos (pero esta es la nota a continuación).
  • Para controlar lo que pueden hacer Apache y PHP), podemos jugar con la parte g de los derechos.
  • La parte o siempre se establece en 0, por lo que nadie más en el servidor puede leer o editar el sitio web.
  • No hay ningún problema cuando bob el usuario crea nuevos archivos, ya que pertenecerá automáticamente a su grupo principal (bob).

Esta es una recapitulación, pero en esta situación, bob está permitido a SSH. Si no debería permitirse a ningún usuario modificar el sitio web (p. Ej., El cliente solo modifica el sitio web a través de un panel de administración de CMS y no tiene conocimiento de Linux), cree dos usuarios de todos modos, pero proporcione /bin/false como Shell para bob también, y deshabilita su inicio de sesión.

    adduser --home /var/www/bobwebsite --Shell /bin/bash bob
    adduser --no-create-home --Shell /bin/false --disabled-login --ingroup bob bob-www
    adduser www-data bob
    cd /var/www/bobwebsite
    chown -R bob:bob .
    find -type d -exec chmod 750 {} \;
    find -type f -exec chmod 640 {} \;

Nota: las personas tienden a olvidar que limitar los derechos (propietario) es inútil e inseguro la mayor parte del tiempo, ya que el propietario de un archivo puede ejecutar el chmod comando, incluso los derechos son 000.

Dime si mi enfoque tiene algunos problemas de seguridad, porque no estoy 100% seguro, pero es lo que estoy usando.

Creo que esta configuración tiene un problema: cuando PHP/Apache crea un nuevo archivo (por ejemplo, subir), pertenecerá a bob-www: bob, y bob solo ser capaz de leerlo Quizás setuid en el directorio puede resolver el problema.

14
Fox

Dado el rango de Google en la excelente respuesta anterior, creo que hay una cosa que debe tenerse en cuenta, y parece que no puedo dejar una nota después de la respuesta.

Continuando con el ejemplo, si planea usar www-data como propietario y dev-fabrikam como grupo con 570 permisos en el directorio (o archivo), es importante tener en cuenta que Linux ignorasetuid, por lo que todos los archivos nuevos serán propiedad del usuario que los creó. Esto significa que después de crear nuevos directorios y archivos, tendrá que usar algo similar a:

chown -R www-data /newdirectory/
chmod -R 570 /newdirectory/

En Ubuntu 12.04 para Rackspace OpenStack, tuve un problema extraño en el que no pude obtener los permisos 570 para trabajar hasta que reinicié el servidor, lo que solucionó mágicamente el problema. Estaba perdiendo pelos a un ritmo cada vez mayor sobre ese problema aparentemente simple ...

9
Paul

Cuando tiene un usuario FTP llamado "leo" necesita cargar archivos en el directorio web de example.com y también requiere que su usuario "Apache" pueda crear archivos uploa-files/sessions/cache en el directorio cache y haga lo siguiente:

Este comando asigna a Leo como propietario y al grupo como Apache a example.com, el usuario de Apache es parte del grupo Apache, por lo que heredará los permisos del grupo Apache

chown -R leo: Apache example.com

Otro comando que asegura el permiso correcto y cumple con las preocupaciones de seguridad también.

chmod -R 2774 example.com

Aquí, el primer número 2 es para el directorio y asegura que cada nuevo archivo creado permanecerá en el mismo grupo y permisos de propietario. 77 es para propietario y grupo significa que tienen acceso total. 4 es para otros significa que solo pueden leer a través.

lo siguiente es útil para comprender los números de permiso

Number  Octal Permission Representation
0   No permission
1   Execute permission
2   Write permission
3   Execute and write permission: 1 (execute) + 2 (write) = 3
4   Read permission
5   Read and execute permission: 4 (read) + 1 (execute) = 5
6   Read and write permission: 4 (read) + 2 (write) = 6
7   All permissions: 4 (read) + 2 (write) + 1 (execute) = 7
3
Krishan Gopal

Voy con esta configuración:

  1. Todos los directorios excepto sube un conjunto al propietario root y al grupo root, permisos para 0755.
  2. Todos los archivos configurados como propietario root y grupo root, permisos para 0644.
  3. Sube el conjunto de directorios al propietario root, grupo www-data, permisos para 1770. El bit adhesivo no permite que el propietario del grupo elimine o cambie el nombre del directorio y los archivos dentro.
  4. Dentro carga la carpeta un nuevo directorio con www-data propietario usuario y grupo, y 0700 permisos para cada www-data usuario que sube archivos.
  5. Configuración de Apache:

Denegar AllowOverride y Index en el directorio de cargas, para que Apache no lea .htaccess archivos, y el usuario de Apache no puede indexar el contenido de la carpeta de cargas:

<Directory /siteDir>
   Options -Indexes
</Directory>

<Directory /siteDir/uploadDir>
   AllowOverride none
</Directory>

6. php.ini configuración:

open_basedir = /siteDir:/tmp:/usr/share/phpmyadmin
post_max_size = 5M
file_uploads = On
upload_max_filesize = 3M
max_file_uploads = 20

Con esta configuración, el www-data el usuario no podrá acceder a directorios que no sean siteDir//tmp y /usr/share/phpmyadmin. También puede controlar el tamaño máximo de archivo, el tamaño máximo de publicación y los archivos máximos para cargar en la misma solicitud.

3
Manolo

OMI uno tiene que tener en cuenta:

  • ¿Confía en un proceso que lee sus archivos? p.ej. PHP?

Supongamos que tiene un servidor que varios datos bajo 'prueba' del usuario.

El usuario 'prueba' tiene allí:

  • sus datos en $HOMEDIR
  • su correo en $MAIL
  • sus datos para web en /var/www/test

Ahora pensemos en:

  • una aplicación web se ejecuta bajo test usuario (PHP-FPM) - ¡puede eliminar cualquiera de sus archivos!
  • una aplicación web se ejecuta en test group (PHP-FPM): puede eliminar cualquiera de sus archivos donde el directorio tiene 'w' para el grupo y puede modificar cualquier archivo que tenga 'r' para el grupo; y aún podría leerlos, ¡tus claves ssh, por ejemplo!

Supongamos que PHP tiene errores, y lo es, ¿confía en su open_basedir? ¿Usted chroot su PHP proceso? ¿Qué es lo que no hace, quiere que rastree a través de todo el sistema de archivos?

Su proceso de aplicación web, por ejemplo. PHP-FPM, entonces debería:

  • estar restringido a una ruta específica a través de chroot
  • no debe ejecutarse con el permiso de usuario primario o grupo primario del propietario de los datos

Así puedes hacer:

  • el usuario de prueba es: test:test
  • el usuario de prueba está en un grupo secundario, por ejemplo. test-www
  • una aplicación web (PHP-FPM) se ejecuta bajo test-www:test-www
  • prueba de usuario si quiere que la aplicación web pueda leer sus archivos hará: chmod u=rwX,g=rX,o= /var/www/test/public
  • pruebe al usuario si quiere que la aplicación web pueda escribir en su ruta de datos web: chmod u=rwX,g=rwXs,o= /var/www/test/public/upload (por lo tanto, la aplicación creará nuevos archivos como: test-www:test-www - ¡tendrá el grupo test-www debido a setgid en el directorio!)

Por lo tanto, si el proceso de la aplicación web fuera falso, solo leería archivos específicos que tendrían lectura grupal y sería capaz de escribir solo en el directorio upload. Recomiendo encarecidamente tener ese upload dir en un sistema de archivos con noexec,nodev,nosuidmount opciones y tiene un monitoreo constante para cualquier nuevo archivo bizzare en ese directorio, además de monitorear cualquier proceso nuevo en test-www uid.

En Linux, uno podría usar ACL para ajustar mejor los permisos. Si más de un humano debiera cargar datos web, sería mejor dividir la cuenta humana de la cuenta utilizada para cargar archivos de datos web, es decir. para crear una nueva cuenta, por ejemplo. test-upload, y el usuario de prueba administraría las claves ssh para restringir qué humano podría ssh/sftp allí. sshd_config conoce ExposeAuthInfo opciones, por lo que se puede configurar para registrar qué clave ssh se utilizó para cargar los datos.

Realmente dudo que la mayoría de los servicios de alojamiento web se preocupen por la separación de privilegios, cuando escriben 'seguro' sin ninguna información de lo que obtienes, diría que mienten.

1
Jiri B