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é protegido contra 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.
Respuestas:
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 el
www-data
usuario, pero puede ser diferente. Useps aux | grep httpd
ops 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 los permisos del sistema de archivos, por lo que no repetiré todo aquí. Pero hay algunas cosas que debe tener en cuenta.
Los
scripts interpretados de bit de ejecución (por ejemplo, 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 los permisos de los archivos recién creados, por lo que el valor común de 022 da como resultado la creación de archivos con 755. Al colaborar 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 cargar el archivo.
El problema con 777
Cuando usted es
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 a cualquier usuario ejecutar cualquier ejecutable como root.
Definir los requisitos.
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 al grupo rx.
En su caso, Eve, cuyo nombre de usuario podría ser
eve
, es el único usuario que mantienecontoso.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.
El beneficio de esta configuración es que se hace más difícil (pero no imposible *) que otros usuarios en el sistema espíen, ya que solo los usuarios y los propietarios de grupos 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 estarán predeterminados en 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.
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.
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.
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.
Si tiene carpetas que Apache debe poder escribir, puede modificar los valores de permiso para el propietario del usuario para que www-data tenga acceso de escritura.
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 la 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 las 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 a salvo. Podría valer su peso en oro si alguna vez necesita reconstruir su sitio web por alguna razón.
fuente
apache
en sistemas derivados de Red Hat.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:
cache/
ouploads/
, donde también se necesita el permiso de "escritura". Para darle a PHP FastCGI esta capacidad, se ejecutará como bob-www , y se agregará bob-www al grupo bob creado automáticamente .AllowOverride
está configurado en algo diferenteNone
. Para evitar usar la parte o de los derechos, agrego el usuario www-data al grupo bob .Ahora:
Esta es una recapitulación, pero en esta situación, se le permite a Bob 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
también un shell para bob , y deshabilitar su inicio de sesión.Nota: las personas tienden a olvidar que limitar los derechos de u (propietario) es inútil e inseguro la mayoría de las veces, 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 podrá leerlo. Quizás setuid en el directorio puede resolver el problema.
fuente
setuid
. Los archivos nuevos siempre son propiedad del creador.bob
. ¿Cómo lidias con eso? P.ej. a través de ssh, ambos usuarios inician sesión como bob. bob (1) siente que él / ella no puede recordar la contraseña y la cambia a otra pero aún segura. bob (2) intenta iniciar sesión la próxima vez, y él / ella no puede.Dado el ranking 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 ignora
setuid
, por lo que todos los archivos nuevos serán propiedad de usuario que los creó. Esto significa que después de crear nuevos directorios y archivos, tendrá que usar algo similar a: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ó el problema mágicamente. Estaba perdiendo pelos a un ritmo cada vez mayor sobre ese problema aparentemente simple ...
fuente
Voy con esta configuración:
root
y al gruporoot
, permisos para0755
.root
y gruporoot
, permisos para0644
.root
, grupowww-data
, permisos a1770
. El bit adhesivo no permite que el propietario del grupo elimine o cambie el nombre del directorio y los archivos dentro.www-data
usuario propietario y el grupo, y0700
permisos para cadawww-data
usuario que carga archivos.Denegar
AllowOverride
yIndex
en el directorio de cargas, para que Apache no lea los.htaccess
archivos, y el usuario de Apache no pueda indexar el contenido de la carpeta de cargas:6.
php.ini
configuración:Con esta configuración, el
www-data
usuario no podrá acceder a directorios que no seansiteDir/
/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.fuente
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
Otro comando que asegura el permiso correcto y cumple con las preocupaciones de seguridad también.
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 completo. 4 es para otros significa que solo pueden leer a través.
lo siguiente es útil para comprender los números de permiso
fuente
OMI uno tiene que tener en cuenta:
Supongamos que tiene un servidor que varios datos bajo 'prueba' del usuario.
El usuario 'prueba' tiene allí:
$HOMEDIR
$MAIL
/var/www/test
Ahora pensemos en:
test
usuario (PHP-FPM): ¡puede eliminar cualquiera de sus archivos!test
grupo (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
? ¿chroot
Tu proceso PHP? ¿Qué es lo que no haces? ¿Quieres que rastree todo el sistema de archivos?Su proceso de aplicación web, por ejemplo. PHP-FPM, entonces debería:
chroot
Así puedes hacer:
test:test
test-www
test-www:test-www
chmod u=rwX,g=rX,o= /var/www/test/public
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
upload
solo en el directorio. Recomendaría encarecidamente tener eseupload
directorio en un sistema de archivos connoexec,nodev,nosuid
mount
opciones y tener un monitoreo constante de cualquier archivo bizzare nuevo en ese directorio, además de monitorear cualquier proceso nuevo bajotest-www
uid.En Linux, uno podría usar ACL para ajustar mejor los permisos. Si más de un humano debe 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 lasExposeAuthInfo
opciones, por lo que se puede configurar para registrar qué clave ssh se usó 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.
fuente
chroot
yuser
,group
se configurará para un grupo. Pero no confiaría en laphp_admin_value[open_basedir]
opción. También leí que es mejor tener un maestro PHP-FPM separado por usuario, vea ma.ttias.be/a-better-way-to-run-php-fpm Para crear instancias de un demonio es fácil en la mayoría de las distribuciones de Linux y * BSD.