Generalidades
suEXEC (que quiere decir "switch user execution" o "cambiar la ejecución del usuario") permite que los usuarios de Apache corran CGI y programas SSI en diferentes usuarios. Cuando se usa correctamente, reduce considerablemente los riesgos de seguridad relacionados con permitir que los usuarios desarrollen y ejecuten programas CGI o SSI privados.
Seguridad
Permisos de Script
suEXEC requiere que todos los scripts CGI y los directorios en los que residen solo puedan ser escritos por el propietario. Si los permisos no están configurados correctamente, ser mostrará 500 Internal Server Error.
El script también debe ser ejecutable. Puedes establecer permisos iniciando sesión en tu servidor vía SSH y corriendo el comando chmod. Por ejemplo:
[server]$ chmod 755 script.cgi
Verificación de variables de entorno
suEXEC solo pasa a través de variables de entorno que se consideran seguras.
En los siguientes ejemplos, username sería tu usuario Shell y example.com tu sitio web.
Ejemplo de suEXEC
Debido a que suEXEC solo permite variables consideradas seguras por la configuración del servidor, las directivas proporcionadas por mod_env como SetEnv, PassEnv, y SetEnvIf no funcionan como se espera.
Los siguientes pasos crean un ejemplo simple de cómo funciona suEXEC en DreamHost.
Paso 1 — Agregar un archivo a tu sitio
Crea un archivo llamado foobar.cgi con el siguiente contenido.
#!/usr/bin/perl use strict; use CGI; $ENV{FOOBAR} ||= 'default'; my $q = CGI->new; print $q->header(); print $ENV{FOOBAR};
Coloca este archivo en dos sitios web diferentes con el mismo nombre de usuario. Por ejemplo:
- /home/username/example.com
- /home/username/example2.com
Paso 2 — Agrega un archivo .htaccess para cada directorio
En el directorio example.com, agrega un .htaccess con la siguiente directiva:
SetEnv FOOBAR foo
En el directorio example2.com, agrega un .htaccess con la siguiente directiva:
SetEnv FOOBAR bar
Paso 3 — Visita los archivos en un buscador
Visita example.com/foobar.cgi en tu buscador. Esperarías que se mostrara foo.
Visita example2.com/foobar.cgi en tu buscador. Esperarías que se mostrara bar.
En vez, default se muestra en ambas páginas.
Explicación
SetEnv está funcionando correctamente para establecer la variable de entorno. El problema es que suEXEC no lo está pasando a tu script CGI.
Soluciones alternativas
Las siguientes secciones te ofrecen algunas formas para que las variables de tu ambiente trabajen como se espera.
Opción 1: Anteponer HTTP_ a la variable del nombre
La configuración de DreamHost de suEXEC permite cualquier variable de entorno que comience con HTTP_ pase.
Cambia tu archivo .htaccess a lo siguiente:
SetEnv HTTP_FOOBAR foobar
luego usa lo siguiente en tu script de CGI.
$ENV{HTTP_FOOBAR}
Esto te permite funcionar como se esperaba.
Cuando usar esta opción
Esta solución se adapta mejor a las aplicaciones que estás desarrollando tú mismo.
Explorar el código fuente de las aplicaciones de terceros (especialmente las aplicaciones grandes, que pueden tener cientos de miles de líneas) y cambiar cada instancia de $ENV{FOOBAR} a $ENV{HTTP_FOOBAR} sería prohibitivamente complejo y requeriría mucho tiempo, sin mencionar que tendrías que rehacer todo ese trabajo cada vez que actualices la aplicación.
Opción 2: Editar el script CGI para configurar la variable en sí
Coloca $ENV{FOOBAR} = 'foo'; en la parte superior del script. Por ejemplo:
#!/usr/bin/perl
use strict;
use CGI;
$ENV{FOOBAR} = 'foo';
$ENV{FOOBAR} ||= 'default';
my $q = CGI->new;
print $q->header();
print $ENV{FOOBAR};
Cuando usar esta opción
Al igual que la Opción 1, esta solución se adapta mejor a las aplicaciones que estás desarrollando tú mismo.
Sin embargo, ten en cuenta que el propósito de usar variables de entorno es alterar el comportamiento de tu secuencia de comandos en función del contexto (o entorno) desde el que se ejecuta. Si configuras la variable desde el propio script, el comportamiento del script es el mismo independientemente del contexto desde el que se ejecute.
Opción 3: Crear un script envoltorio
Crea un archivo llamado wrapper.cgi con el siguiente contenido:
#!/bin/sh
export FOOBAR=foo
exec /home/username/example.com/foobar.cgi
Luego agrega el contenido a tu archivo .htaccess para redirigir los requerimientos del script a wrapper.cgi:
RewriteEngine On
RewriteRule ^script.cgi /wrapper.cgi
- Como puedes imaginar, simplemente continuar agregando RewriteRules más allá de algunos scripts se vuelve difícil de manejar. En cambio, es mejor hacer coincidir todos los archivos que terminan con una extensión de archivo específica. Haciendo coincidir solo los archivos que terminan en .cgi, .pl, .py, .rb, y así, los archivos estáticos, como documentos HTML e imágenes, no se ven afectados.
- Si la secuencia de comandos de tu envoltorio está en el mismo directorio que las secuencias de comandos que deseas envolver y estás haciendo coincidir el patrón (esto no importa si estás haciendo coincidir un nombre de archivo específico), tu envoltorio debe tener una extensión de archivo diferente a la de tus secuencias de comandos. . Por ejemplo, si tu envoltorio termina en.cgi, es posible que desees usar lo siguiente para las extensiones .pl y .py.
RewriteRule .*\.pl wrapper.cgi RewriteRule .*\.py wrapper.cgi
- wrapper.cgi puede llamar a un script fuera del directorio de tu dominio. Esto es probablemente lo que en realidad quieras hacer, ya que el envoltorio en ambos /home/username/example.com/ y /home/username/example2.com puede referirse a los mismos scripts en /home/username.
- Si estás configurando variables de entorno para una aplicación, puedes especificar el directorio de la aplicación en su lugar. Por ejemplo:
RewriteEngine On RewriteRule ^application/.*\.cgi /wrapper.cgi
Cuando usar esta opción
La Opción 3 es complicada pero es adecuada para una gama mucho más amplia de casos
A diferencia de la Opción 1, puedes establecer una variable ambiental para cientos (o miles) de archivos editando solo dos archivos (wrapper.cgi y .htaccess).
Y, cuando configuras una variable ambiental para una aplicación de terceros, no tienes que modificar ningún archivo cuando actualiza la aplicación.
Puedes tener varias secuencias de comandos envoltorios, por lo que, a diferencia de la Opción 2, el contexto (o el entorno) puede alterar el comportamiento de las secuencias de comandos. Simplemente copia wrapper.cgi y .htaccess de example.com a example2.com, edita wrapper.cgi, y luego cambia export FOOBAR=foo a export FOOBAR=bar, y ya estás listo.