El código de host virtuales ha sido completamente reescrito en Apache 1.3. Este documento intenta explicar qué hace exactamente Apache cuando debe decidir desde qué host virtual debe servir una petición. Con la ayuda de la nueva directiva NameVirtualHost la configuración de un host virtual es algo más fácil y seguro que con las versiones anteriores a la 1.3.
Si únicamente quiere hacerlo funcionar sin entender cómo, aquí tiene algunos ejemplos.
Existe un servidor principal que consiste en todas las definiciones
que están fuera de las secciones llamadas <VirtualHost>
.
Existen los servidores virtuales, llamados vhosts, que están definidos dentro
de las secciones <VirtualHost>.
Las directivas Port, ServerName, ServerPath, y ServerAlias pueden aparecer en cualquier parte dentro de la definición de un servidor. Sin embargo, cada vez que aparecen sobreescriben el valor anterior (dentro de ese servidor).
El valor por defecto del campo Port
para el servidor principal
es 80. El servidor principal no tiene una valor por defecto para ServerPath
o
para ServerAlias
. El valor por defecto de ServerName
se obtiene
de la dirección IP de los servidores.
La directiva Port del servidor principal tiene dos funciones mantenidas por compatibilidad
con los ficheros de configuración de NCSA. Una de las funciones es para determinar el puerto
de red por defecto al que Apache escuchará. Este valor se sobreescribe con el valor de las
directivas Listen
. La segunda función
es para especificar el número de puerto que se usa en URIs absolutas durante las
redirecciones.
A diferencia del servidor principal, los puertos del host virtual NO afectan a los puertos que Apache atiende en las conexiones.
Cada dirección que aparece en la directiva VirtualHost
puede tener
un puerto opcional. Si no se especifica, toma el valor de la declaración Port
más reciente. El puerto especial * indica cualquier puerto. El conjunto completo
de direcciones (incluyendo múltiples registros de tipo A búsquedas DNS)
se llaman conjunto de direcciones del host virtual.
A menos que se especifique una directiva
NameVirtualHost para una dirección IP específica, el primer host virtual con esa
dirección es tratado como un host virtual basado en IP. La versión 1.3.13 de Apache y
posteriores la dirección IP *
.
Si se utiliza host virtuales basados en nombre, se debe poner la directiva
Se pueden utilizar múltiples directivas El orden de las directivas (Para mejorar la legibilidad de su fichero de configuración quizás prefiera la
variante de la izquierda).
Después de comprobar la directiva La lista completa de nombre en la directiva Durante la inicialización se genera e inserta en una tabla hash una lista para
cada dirección IP. Si la dirección se utiliza en una directiva
Gracias a una rápida función hash, el hecho de sobrecargar una tabla hash con
direcciones IP durante una petición es mínima o incluso nula. Además, la tabla está
optimizada para direcciones IP que varían en su último octeto.
Para cada host virtual se fijan varios valores por defecto, particularmente:
Si el principal no tiene ningún Para cualquier campo A cualquier host virtual que incluya _default_ se le da el mismo
Para una petición dada, el servidor determina qué host virtual usar de este modo:
Cuando el cliente realiza la primera conexión, la dirección IP a la que el cliente
conectó se busca en la tabla hash interna.
Si la búsqueda no tiene éxito (no se encontró la la dirección IP), la petición se
sirve desde el host virtual _default_, siempre que éste exista para el
puerto al que el cliente envió la petición. Si esto último tampoco ha tenido éxito,
la petición se sirve desde el servidor principal.
En Apache 1.3.13 y versiones posteriores, si la dirección IP no se encuentra en la tabla
hash, pero sí concuerda el puerto, puede dar como resultado una entrada correspondiente
a un Si la búsqueda tuvo éxito (se encontró una entrada para la dirección IP), el siguiente
paso consiste en decidir si hay que tratar con un host virtual basado en IP o basado en
nombre.
Si la entrada que se ha encontrado tiene una lista de nombres vacía,
entonces significa que tenemos un host virtual basado en IP, por lo que
no se realiza ninguna otra acción y la petición se sirve desde ese host
virtual.
Si la entrada corresponde a un host virtual basado en nombre, la lista
de nombres contendrá una o más estructuras de host virtuales. Esta lista
contiene los host virtuales en el mismo orden en que aparecen en las
directivas El primer host virtual de esta lista (el primer host virtual en el fichero
de configuración con la dirección IP especificada) tiene la más alta prioridad
y se "apodera" de cualquier petición a un servidor desconocido o de cualquier
petición sin el campo de cabecera Si el cliente proporciona un campo de cabecera Si el cliente envió una petición HTTP/1.0 sin el campo Si no se pudo encontrar ningún host virtual que concuerde, la petición será servida
por el primer host virtual cuyo puerto coincida en la lista con la IP a la que el
cliente conectó, tal y como se mecionó antes.
Si el URI de una petición es absoluto y su nombre de host y puerto coiciden con el
el servidor principal o uno de los host virtuales configurados y además coincide
con la dirección y puerto al que el cliente envió la petición, entonces se quita el prefijo
esquema/nombre host/puerto y el URI restante se sirve por el correspondiente servidor
principal o host virtual. Si no concuerda, el URI permanece intacto y la petición se
considera como una petición de proxy.
Además de las recomendaciones sobre cuestiones
relacionadas con DNS, aquí tiene algunas otras:
NameVirtualHost
con la dirección IP para ese host virtual. En otras
palabras; debe especificar por medio de la directiva NameVirtualHost
la dirección IP que tengan los alias de host (los registros
CNAMEs) de sus host virtuales basados en nombre.
NameVirtualHost
con un conjunto
de directivas VirtualHost
, pero sólo una directiva
NameVirtualHost
debería ser usada para cada para IP:puerto.
NameVirtualHost
y
VirtualHost
no es importante, lo quq hace que los siguientes ejemplos
sean idénticos (solamente el orden de las directivas
VirtualHost
para un conjunto de direcciones es importante. Véalo
abajo):
|
NameVirtualHost 111.22.33.44 | <VirtualHost 111.22.33.44>
<VirtualHost 111.22.33.44> | # servidor A
# servidor A | </VirtualHost>
... | <VirtualHost 111.22.33.55>
</VirtualHost> | # servidor C
<VirtualHost 111.22.33.44> | ...
# servidor B | </VirtualHost>
... | <VirtualHost 111.22.33.44>
</VirtualHost> | # servidor B
| ...
NameVirtualHost 111.22.33.55 | </VirtualHost>
<VirtualHost 111.22.33.55> | <VirtualHost 111.22.33.55>
# servidor C | # servidor D
... | ...
</VirtualHost> | </VirtualHost>
<VirtualHost 111.22.33.55> |
# servidor D | NameVirtualHost 111.22.33.44
... | NameVirtualHost 111.22.33.55
</VirtualHost> |
|
VirtualHost
, al servidor virtual
se le asigna un puerto
igual al que se asignó al primer nombre en su
directiva VirtualHost
.
VirtualHost
es tratada
como un ServerAlias
(pero su valor no se sobreescribe con ninguna
declaración ServerAlias
) siempre que todos los nombres se resuelvan en
el mismo conjugo de direccionest. Tenga en cuenta que las declaraciones Port
subsiguientes para este host virtual no afectarán a los puertos asignados en el
conjunto de direcciones.
NameVirtualHost
, la lista contendrá todos los host virtuales basados
en nombre para esa dirección IP. Si no se definió ningún host virtual, la
directiva NameVirtualHost
es ignorada y se guarda un error en el fichero
de logs. Si se da el caso de que se utiliza host virtual basado en IP, la tabla
hash permanece vacía.
Básicamente, el servidor principal es tratado como "por defecto" o como
"base" sobre el que se levanta cada host virtual. Sin embargo, la posición
de las definiciones en el fichero de configuración del servidor principal es totalmente
irrelevante; el fichero de configuración es "parseado" (chequeado) una vez que la
"mezcla" de valores se haya llevado a cabo. Así que, si una definición en el servidor
principal aparece después de una definición en el host virtual, podría afectar
a la definición del host virtual.
ServerAdmin
,
ResourceConfig
,
AccessConfig
,
Timeout
,
KeepAliveTimeout
,
KeepAlive
,
MaxKeepAliveRequests
,
o
SendBufferSize
,
entonces el valor respectivo se toma del servidor principal. Es decir, se
hereda el último valor que tuviera en el servidor principal, cualquiera
que sea.
ServerName
, se usará el nombre
de host de la máquina sobre la que httpd esté corriendo. Llamaremos a las
direcciones devueltas por una búsqueda en DNS que aparecen en ServerName
del servidor principal conjunto de direcciónes del servidor principal.
ServerName
no definido, el host virtual basado
en nombre toma como valor por la primera dirección proporcionada por la declaración
VirtualHost
que define el host virtual.
ServerName
que el servidor principal.
Concordancia de host virtual
Búsqueda en una tabla hash
NameVirtualHost *
, que es entonces manejado como cualquier otro host
virtual basado en nombre.
Host virtual basado en nombre
Host virtual basado en nombre
VirtualHost
del fichero de configuración.
Host:
.
Host:
, entonces
se busca en la lista una concordancia de un host virtual y se toma la primera ocurrencia
en ServerName
o ServerAlias
, siendo la petición servida desde
ese host virtual. Un campo de cabecera Host:
puede contener un número de
puerto, pero Apache siempre busca la concordancia contra el puerto real al que el
cliente envió la petición.
Host:
,
no sabríamos a qué servidor intenta conectar, por lo que cualquier ServerPath
concordará con el URI de la petición. De este modo, la primera concordancia en la lista
será la usada y la petición será servida desde ese host virtual.
Conexiones persistentes
El modo de búsqueda descrito arriba se realiza solamente una vez por cada sesión
TCP/IP, mientras que la búsqueda de nombre se realiza por cada petición en una
conexión persistente. En otras palabras, un cliente puede pedir páginas desde diferentes
host virtuales basados en nombre durante una única conexión persistente.
URI absoluto
Observaciones
NameVirtualHost
.
ServerAlias
y ServerPath
para host
virtuales basados en IP.
NameVirtualHost
dentro del fichero de configuración
no es importante. Sólo el orden de un host virtual basado en nombre para un
conjunto específico de direcciones es importante. El host virtual basado en nombre
que esté primero en el fichero de configuración tiene la más alta prioridad
para su conjunto de direcciones.
Host:
no se usa nunca en el proceso de concordancia. Apache siempre usa el puerto real
al que el cliente envió la petición.
ServerPath
que sea prefijo de otra directiva
ServerPath
que aparezca más tarde en el fichero de configuración, entonces
la concordancia será contra el primero y nunca con el segundo. Esto es así asumiendo
que el campo de cabecera Host:
esté presente para evitar ambigûedades.
_default_
toma una petición solamente si no hay ningún
otro host virtual que coincida con la dirección IP y el número de puerto
de la petición. Sólo se toma la petición si el número de puerto al que el cliente
envió la petición coincide con el número de puerto de del servidor virtual
_default_
que sea el Port
estándar por defecto. Se puede
usar un carácter comodín (por ejemplo
_default_:*
) para tomar peticiones a cualquier puerto disponible.
En Apache 1.3.13 y posteriores esto también sirve para host virtuales
NameVirtualHost *
.
_default_
).
En otras palabras, el servidor principal solo coge peticiones para combinaciones
dirección/puerto sin especificar (a menos que haya un host virtual
_default_
que concuerde con ese puerto).
_default_
o el servidor principal concuerdan
con una petición que no tenga el campo Host:
(o este no sea válido) cuando
el cliente conectó con una dirección y puerto que sea usado por un host virtual basado
en nombre, como en una directiva NameVirtualHost
.
VirtualHost
porque forzará a su servidor a confiar en DNS para arrancar. Más aún, es una amenaza
a la seguridad si no controla el DNS para todos los dominios listados. Puede encontrar
más información sobre esto en los siguientes apartados.
ServerName
para cada host virtual. De otro modo
se requerirá una consulta a DNS por cada host virtual.
Recomendaciones
VirtualHost
. Esto ayudará a la legibilidad
de la configuración.
NameVirtualHost
y
VirtualHost
para mejorar la legibilidad del fichero de
configuración.
ServerPaths
que son prefijos de otros
ServerPaths
. Si no puede evitarlos, asegúrese de que el más largo
prefijo (más específico) del host virtual aparezca antes en el fichero de configuración
que el más corto (menos específico). Por ejemplo, "ServerPath /abc"
debería aparecer después de "ServerPath /abc/def".