Cree subdominios sobre la marcha con .htaccess (PHP)

122

Estoy buscando crear un sistema que al registrarse creará un subdominio en mi sitio web para el área de cuenta de los usuarios.

por ejemplo, johndoe.website.com

Creo que sería algo que ver con el archivo .htaccess y posiblemente redirigir a otra ubicación en el sitio web. En realidad no lo se. Pero cualquier información para comenzar sería muy apreciada.

Crear un área de registro no es el problema, lo he hecho muchas veces. No estoy seguro de dónde comenzar con el subdominio.

Ben McRae
fuente

Respuestas:

125

El resumen rápido

  1. Debe crear un dominio comodín en su servidor DNS * .website.com
  2. Luego, en su contenedor vhost, también deberá especificar el comodín * .website.com: esto se hace en los ServerAlias DOC
  3. Luego extraiga y verifique el subdominio en PHP y muestre los datos apropiados

La versión larga

1. Crear una entrada DNS comodín

En su configuración de DNS, debe crear una entrada de dominio comodín como *.example.org. Una entrada comodín tiene este aspecto:

*.example.org.   3600  A  127.0.0.1

2. Incluya el comodín en vhost

A continuación, en la configuración de Apache, debe configurar un contenedor vhost que especifique el comodín en la directiva ServerAlias DOC . Un ejemplo de contenedor vhost:

<VirtualHost *:80>
  ServerName server.example.org
  ServerAlias *.example.org
  UseCanonicalName Off
</VirtualHost>

3. Determine en qué subdominio se encuentra en PHP

Luego, en sus scripts PHP, puede encontrar el dominio buscando en la $_SERVERvariable súper global. Aquí hay un ejemplo de agarrar el subdominio en PHP:

preg_match('/([^.]+)\.example\.org/', $_SERVER['SERVER_NAME'], $matches);
if(isset($matches[1])) {
    $subdomain = $matches[1];
}

He usado regex aquí para permitir que las personas accedan a su sitio a través de www.subdomain.example.org o subomain.example.org.

Si nunca anticipa tener que lidiar con www. (u otros subdominios), entonces simplemente podría usar una subcadena como esta:

$subdomain = substr(
                 $_SERVER['SERVER_NAME'], 0,
                 strpos($_SERVER['SERVER_NAME'], '.')
             );

Hosting virtual masivo

El alojamiento virtual masivo es un esquema ligeramente diferente al anterior, ya que generalmente lo usaría para alojar muchos sitios web distintos en lugar de intentar usarlo para alimentar una aplicación como lo propone la pregunta.

He documentado mi entorno de alojamiento virtual masivo basado en mod_rewrite antes en una publicación en mi blog , que podría ver si esa es la ruta que desea tomar. También existe, por supuesto, la página de manual de Apache respectiva .

Apache también tiene una forma interna de tratar con el alojamiento virtual masivo que es un poco menos flexible que el método mod_rewrite que he usado. Todo esto se describe en la página del manual de Apache Virtual Mass Hosting configurado dinámicamente .

Treffynnon
fuente
Siempre que pueda usar wildcard subdomains, vea mi solución para hacerlo .htaccess.
Dan Bray
No creo que se pueda agregar un host virtual desde .htaccess, también me pone nervioso acerca de la seguridad. A partir de 2.4, debería ser posible seleccionar un directorio base dependiente del nombre de host (pero el método de Dan también tiene algunos problemas) Considere:RewriteRule "^/?(.*)" "http://%{HTTP_HOST}/%{HTTP_HOST}/$1" [L,R,NE]
symcbean
Tenga en cuenta que el código PHP que implementa esto NO DEBE ejecutarse como el uid del servidor web (debe ser como un usuario dedicado a través de sudo)
symcbean
12

Puede permitir cada subdominio en primer lugar y luego verificar si el subdominio es válido. Por ejemplo:

RewriteEngine on
RewriteCond %{HTTP_HOST} ^[^.]+\.example\.com$
RewriteRule !^index\.php$ index.php [L]

Dentro del index.phppuede extraer el subdominio usando:

if (preg_match('/^([^.]+)\.example\.com$/', $_SERVER['HTTP_HOST'], $match)) {
    var_dump($match[1]);
}

Pero todo esto requiere que su servidor web acepte cada nombre de subdominio.

Gumbo
fuente
3
Además, requiere que su servidor DNS resuelva cada nombre de subdominio.
caos
1
He visto esto en otros sitios web, seguramente no tienen que resolver cada subdominio cada vez que lo hacen.
Ben McRae
1
Bueno, depende de lo que quieras decir con eso. Si quiere decir, cada vez que alguien en Internet busca foo.somedomain.com y no está en caché, su servidor DNS tiene que resolverlo, entonces sí.
caos
Si quiere decir, ¿tienen que configurar registros DNS específicamente para cada dominio? Vea la respuesta de Treffynnon.
caos
ok gracias por eso No entiendo muy bien lo que significa Treffynnon al especificar el comodín en el vhost.
Ben McRae
6

Me resultó más fácil hacerlo con PHP. De hecho, es crear un subdominio dentro de cPanel y crear su carpeta con el nombre de dominio deseado. Como lo hará manualmente en cPanel, pero todo se hace en milisegundos mediante una simple función PHP. No es necesario hacer clic :)

function create_subdomain($subDomain,$cPanelUser,$cPanelPass,$rootDomain) {

    //  $buildRequest = "/frontend/x3/subdomain/doadddomain.html?rootdomain=" . $rootDomain . "&domain=" . $subDomain;

    $buildRequest = "/frontend/x3/subdomain/doadddomain.html?rootdomain=" . $rootDomain . "&domain=" . $subDomain . "&dir=public_html/subdomains/" . $subDomain;

    $openSocket = fsockopen('localhost',2082);
    if(!$openSocket) {
        return "Socket error";
        exit();
    }

    $authString = $cPanelUser . ":" . $cPanelPass;
    $authPass = base64_encode($authString);
    $buildHeaders  = "GET " . $buildRequest ."\r\n";
    $buildHeaders .= "HTTP/1.0\r\n";
    $buildHeaders .= "Host:localhost\r\n";
    $buildHeaders .= "Authorization: Basic " . $authPass . "\r\n";
    $buildHeaders .= "\r\n";

    fputs($openSocket, $buildHeaders);
        while(!feof($openSocket)) {
           fgets($openSocket,128);
        }
    fclose($openSocket);

    $newDomain = "http://" . $subDomain . "." . $rootDomain . "/";

   //  return "Created subdomain $newDomain";

}
Adrian P.
fuente
Verifique si se creó con éxito en cPanel y, verifique por FTP (o administrador de archivos), qué hay dentro de la carpeta public_html / subdominio. Si tiene una configuración de cPanel que agrega cosas cuando crea un subdominio, esto no está relacionado con la creación de subdominios sobre la marcha.
Adrian P.
No no se ha creado en cPanel
Ruchi
Entonces no tienes suficiente permiso en cPanel. ¿Es este VPS de alojamiento compartido o servidor dedicado?
Adrian P.
Puede haber múltiples razones para no crear el subdominio. No está relacionado con el script anterior, pero con su configuración de DNS. Lea eso y solicite ayuda en los foros de cPanel. forums.cpanel.net/threads/subdomains-not-working.228132
Adrian P.
5

La forma más fácil es redirigir todos los subdominios (con comodín *) para que apunten a su / wwwroot. Luego ponga .htaccess a esta carpeta con el siguiente código:

RewriteCond %{ENV:REDIRECT_SUBDOMAIN} ="" 
RewriteCond %{HTTP_HOST} ^([a-z0-9][-a-z0-9]+)\.domain\.com\.?(:80)?$ [NC] 
RewriteCond %{DOCUMENT_ROOT}/%1 -d 
RewriteRule ^(.*) %1/$1 [E=SUBDOMAIN:%1,L] 
RewriteRule ^ - [E=SUBDOMAIN:%{ENV:REDIRECT_SUBDOMAIN},L]

Esto logrará que cada subcarpeta de la carpeta / wwwroot sea aceptable a través del subdominio (foldername.domain.com).

Encontrado hace años en http://www.webmasterworld.com/apache/3163397.htm

Glavić
fuente
4

No tiene nada que ver con .htaccess. Deberá configurar registros DNS y alojamiento virtual para los subdominios.

caos
fuente
4

Mod_vhost_alias es el módulo correcto para hacer esto.

Con una línea puede decirle a Apache que busque el lugar correcto, con hashing de directorios, etc. Por ejemplo, la línea:

VirtualDocumentRoot /http/users/%3.1/%3.2/%3

le indicaría a Apache que establezca la raíz del documento en / http / users / s / u / subdominio cuando se le solicite subdominio.sudominio.com

Julien Tartarin
fuente
0

Creo que el DNS comodín con Dynamic Mass Virtual Hosting de Apache también es una solución razonable. Aunque, nunca lo he intentado.

Si tiene la necesidad de escalar a varios servidores o las otras soluciones simplemente no funcionan para usted, le recomiendo usar un servidor DNS controlado por una base de datos. He utilizado con éxito MyDNS en el pasado. Como utiliza MySQL (o PostgreSQL), puede actualizar su DNS sobre la marcha con PHP o casi cualquier otra cosa. El código no parece que haya sido actualizado desde hace tiempo, pero es DNS y, por lo tanto, no es exactamente lo último.

Barrett Conrad
fuente
0

Métodos de creación de subdominios comodín

Primero debe crear la configuración de DNS utilizando el editor de DNS de su servidor.

  1. Cree un Aregistro en la configuración de DNS con el *comodín del host en la dirección IP del servidor.

    * 1400 IN A ip_address

  2. Cree una vez más un Aregistro en la configuración de DNS con el host @o la domain_name.tlddirección IP del servidor. tld significa dominios de nivel superior o la extensión de dominios como .com, .org, etc.

    @ 1400 IN A ip_address o domain_name.tld 1400 IN A ip_address

  3. Crear CNAMEregistro como:

    www 1400 IN A domainname.tld

  4. Cree el subdominio con *comodín como*.domain.tld
  5. Crea htaccess en tu directorio de subdominio *.domain.tldy pon este código:

    Options +FollowSymLinks 
    RewriteEngine On 
    RewriteBase /
    RewriteRule ^([aA-zZ0-9]+)$ index.php?data=$1
    RewriteCond %{HTTP_HOST} ^([aA-zZ0-9]+)\.([aA-zZ0-9-]+)\.([aA-zZ]+)
    RewriteRule ([aA-zZ0-9]+) index.php?data=%1

    Pruebe su primer subdominio comodín como example.domainname.tld

Si no le interesa pasar los datos como parámetro utilizando htaccess, también puede obtener los datos mediante la siguiente codificación:

define("SUBDOMAIN_PARENT","domainname.tld");   
class getData
    {
         function __construct()
        {
            $this->data="";
            $http_host=$_SERVER['HTTP_HOST'];
         $subdom_data= str_replace(SUBDOMAIN_PARENT,"",$http_host);
         $expl_subdom_data=explode(".",$subdom_data);
      $expl_subdom_data=array_filter($expl_subdom_data);

            if($expl_subdom_data!=NULL)
            {
           $this->data=end($expl_subdom_data);
            }
       }
    }
$GLOBALS['get_data']=new getData();

y usa tu variable global en cualquier lugar como global $get_data.

echo $get_data->data; //example

(nota: esta clase se usa principalmente para obtener el subdominio exacto de http_host. porque algunos nombres adicionales combinados antes de su subdominio también son aplicables como www.example.domainname.tld. Este retorno $_GET['data']='wwww'Entonces, mi sugerencia es usar $_SERVER['http_host']para obtener los valores exactos en lugar de usar el$_SERVER['query_string'] parámetros htaccess pasados ​​en su página de índice)

6. Acelere la ejecución de este subdominio comodín use N segundos en TTL - CONFIGURACIÓN DNS.

7.Compruebe el subdominio después de su tiempo ttl dado (600-10 minutos) como => http://abc.domain.tld

(nota: los subdominios comodín no anulan los subdominios existentes. Porque la primera prioridad siempre es para sus subdominios existentes)

karthikeyan ganesan
fuente