Portas de configuração do Apache em “NameVirtualHost” e “Listen”

3

No Apache ports.conf tenho

NameVirtualHost *:80
Listen 80

Não consigo entender que, como em NameVirtualHost *:80 a porta já está configurada, por que há um Listen 80 separado.

O que isso significa? O que seria se eles fossem diferentes?

    
por McBodik 25.09.2013 / 12:33

3 respostas

2

Listen 80 diz ao Apache para realmente configurar o socket na porta 80, não tem nada a ver com a nomenclatura.

NameVirtualHost *:80 diz ao Apache para se referir às configurações nomeadas do vhost para este endereço / soquete de porta específico, não tem nada a ver com a configuração do soquete.

What would be if they were differents?

A diferença seria que sua configuração seria interrompida e seu servidor não funcionaria.

    
por 25.09.2013 / 21:49
2

Do site da Apache :

The Listen directive does not implement Virtual Hosts - it only tells the main server what addresses and ports to listen on. If no directives are used, the server will behave in the same way for all accepted requests. However, can be used to specify a different behavior for one or more of the addresses or ports. To implement a VirtualHost, the server must first be told to listen to the address and port to be used. Then a section should be created for the specified address and port to set the behavior of this virtual host. Note that if the is set for an address and port that the server is not listening to, it cannot be accessed.

O Apache é muito flexível. A maneira mais básica de usá-lo é sem hosts virtuais. Se você não estiver usando hosts virtuais, poderá usar a diretiva Listen para especificar quais interfaces de rede e portas serão usadas. Você pode especificar basicamente todas as opções que podem ser especificadas em um host virtual diretamente no seu arquivo http.conf (que é como o Apache.org o empacota na última vez que verifiquei o BTW).

As diretivas

VirtualHost são substituições para esse comportamento padrão. Eles dizem ao Apache para tratar certas combinações de IP e porta de maneira diferente. Se o Apache não tivesse os dois, você precisaria usar hosts virtuais. Isso costumava ser um problema maior quando os hosts virtuais foram inventados pela primeira vez. Na época, os navegadores não sabiam como lidar com eles e, embora o suporte tenha sido adicionado a todos os navegadores populares logo depois, muitas pessoas continuaram a usar navegadores desatualizados no momento. Como isso foi há muito tempo, a maioria das distribuições do Apache agora usam hosts virtuais por padrão porque são mais flexíveis e possibilitam uma resposta diferente dependendo do IP, porta ou nome.

Mesmo agora que temos hosts virtuais, o fato de podermos especificar uma configuração padrão para nosso domínio é útil. Considere o caso em que alguém insere um nome de subdomínio inválido. Como temos um site padrão, podemos usá-lo para mostrar uma página personalizada \ site quando alguém tentar acessá-lo.

O tipo reverso de situação também pode ser verdadeiro. Se você quiser, poderá tornar sites-enabled uma pasta compartilhada e ajustar o conteúdo dos arquivos de configuração de portas por servidor para balancear a carga de muitos servidores.

Dito isso, acho estranho que o Apache não tenha uma maneira de defini-los automaticamente com base na configuração do host virtual.

Apenas por diversão, eu escrevi um script que poderia fazer isso funcionar automaticamente. Você pode tentar se quiser, mas eu avisá-lo que você deve ser cauteloso sobre o uso, porque é quase completamente não testado. Significado ISTO NÃO É CÓDIGO DE PRODUÇÃO:

<?php
$path=dirname(__FILE__); // The current file path. It is used so all other paths can reliably be set relatively.

$cfg=array(
   'output_file'=>"$path/var/ports.conf.out", // This is the file to be generated.
   'template_file'=>"$path/tpl_default.php",
   'glob_patterns'=>array( // This array contains a list of directories to search for virtual hosts in.
      "$path/test-enabled/*", // For now I'd just test some copies which you can play with. Once everything is
   ),   // good then you can change this to /etc/apache/sites-enabled

);

##############
define('IS_CLI', PHP_SAPI==='cli');

echo "Auto Vhost Script\n------------------\n\n";

//echo "Arguments: \n"; print_r(arguments($argv));

echo "Output File:\n\t{$cfg['output_file']}\n";
if(!isset($cfg['output_file'])||!is_writable(dirname($cfg['output_file'])))
   die("ERROR: Cannot write to output file.\n");

echo "Template File:\n\t{$cfg['template_file']}\n";
if(!isset($cfg['template_file'])||!is_readable(dirname($cfg['template_file'])))
   die("ERROR: Cannot read to template file.\n");

echo "Search Paths:\n";
foreach($cfg['glob_patterns'] as $pattern) {
   echo "\t$pattern\n";
}
echo "\nReading configuration files...\n";

$vhosts=array();
foreach($cfg['glob_patterns'] as $pattern) {
   echo ">> $pattern\n";
   $files=glob($pattern);
   foreach($files as $file) {
      echo "\t>> ". basename($file) ."\n";
      $handle=@fopen($file, "r");
      if($handle) {
         while(($buffer=fgets($handle, 4096))!==false) {
            $status=procLine($buffer);
            if(!$status) die("ERROR: Failed reading input line.\n");
            if($status===TRUE) continue;
            $vhosts[]=$status;
         }
         if(!feof($handle)) die("ERROR: Unexpected fgets() fail.\n");
         fclose($handle);
      }
   }
}
echo "\n\nGenerating template data...\n";
$nvhost=array();
$listen=array();
foreach($vhosts as $vhost) {
   // We're just going to assume that if you have multiple VirtualHost for the same port that means you want to use
   // *:port . You could improve this by actually checking to see if multiple hosts have been assigned to this port
   // but you'd need to rearrange the data a little.
   if($vhost['is_name']||isset($nvhost[$vhost['port']])) {
      $nvhost[$vhost['port']]='NameVirtualHost *:'.$vhost['port'];
      $listen[$vhost['port']]='Listen '.$vhost['port'];
   } else {
      $nvhost[$vhost['port']]='NameVirtualHost '.$vhost['host'].':'.$vhost['port'];
      if($vhost['host']=='*')
         $listen[$vhost['port']]='Listen '.$vhost['port'];
      else $listen[$vhost['port']]='Listen '.$vhost['host'].':'.$vhost['port'];
   }
}
echo "\n\nWriting output file...\n";

$tpl=file_get_contents($cfg['template_file']);
if($tpl) {
   $tpl=str_replace('{NAME_VHOST}', implode("\n", $nvhost), $tpl);
   $tpl=str_replace('{LISTEN}', implode("\n", $listen), $tpl);
   file_put_contents($cfg['output_file'], $tpl);
}

echo "\n\nDone.\n";

function procLine($line) {
   if(!preg_match("/^(\w)*<VirtualHost(.)*>(\w)*/", $line)) return true;
   $host=substr($line, strpos($line, 'VirtualHost')+12, strlen($line)-strrpos($line, '>')+2);
   $last_square=strrpos($host, ']'); // This is in case the host is specified in IPv6 format
   $cln=strrpos($host, ':');
   if($cln!==FALSE && $cln+1<strlen($host) && $cln>$last_square) {
      $port=substr($host, $cln+1);
      $host=substr($host, 0, $cln);
   } else $port='80';
   $is_range=strpos($host, '*')!==FALSE;
   $is_ip=$is_range||filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE)!==FALSE;
   $is_name=!$is_ip;
   return array('host'=>$host, 'port'=>$port, 'is_name'=>$is_name, 'is_ip'=>$is_ip, 'is_range'=>$is_range);
}

Tudo o que precisa ser configurado é a variável $cfg na parte superior do script e um modelo de arquivo de configuração de portas. Para usá-lo, execute-o com PHP: php path/to/auto_vhost.php . Uma vez que você consiga esse trabalho, você pode adicionar a chamada php a /etc/init.d/apache2 perto do topo (ou se você olhar, existe um lugar um pouco melhor, mas só porque isso realmente não é necessário nos comandos service apache2 stop ). Isso fará com que esse script seja executado logo antes do Apache ser iniciado ou reiniciado, de modo que ele seja carregado.

Aqui está um exemplo de arquivo de modelo para isso:

# This file was generated from a template by auto_vhost.php

{NAME_VHOST}

{LISTEN}

<IfModule mod_ssl.c>
    # If you add NameVirtualHost *:443 here, you will also have to change
    # the VirtualHost statement in /etc/apache2/sites-available/default-ssl
    # to <VirtualHost *:443>
    # Server Name Indication for SSL named virtual hosts is currently not
    # supported by MSIE on Windows XP.
    Listen 443
</IfModule>

<IfModule mod_gnutls.c>
    Listen 443
</IfModule>
    
por 26.09.2013 / 09:09
1

Cada programa, por padrão, precisa de uma porta e Kernel pacotes de envio para programas via port numbers quando você diz:

Listen 80

Você diz ao kernel que o meu apache quer usar a porta 80, quando chegar com a des-porta 80, me dê ..., se você tentar:

root@debian:/home/mohsen# netstat -anp |egrep apache
tcp6       0      0 :::80                   :::*                    LISTEN      25791/apache2   

Quando você altera Listen line, a saída do netstat será alterada.

Mas, Virtualhosts :

Não há porta de conflito, para mais detalhes, leia sobre VirtualHost by name e VirtualHost by IP

    
por 25.09.2013 / 13:02